@oneuptime/common 12.0.5 → 12.0.6
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.
- package/Models/DatabaseModels/AIRun.ts +33 -0
- package/Models/DatabaseModels/DataSource.ts +744 -0
- package/Models/DatabaseModels/Index.ts +3 -0
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
- package/Models/DatabaseModels/User.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
- package/Models/DatabaseModels/UserSession.ts +2 -0
- package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
- package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
- package/Server/API/AIInsightAPI.ts +47 -4
- package/Server/API/AIInvestigationAPI.ts +25 -0
- package/Server/API/DashboardAPI.ts +176 -492
- package/Server/API/DataSourceAPI.ts +268 -0
- package/Server/API/StatusPageAPI.ts +11 -1
- package/Server/API/UserAPI.ts +119 -0
- package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Infrastructure/Queue.ts +26 -0
- package/Server/Infrastructure/QueueWorker.ts +17 -0
- package/Server/Middleware/TelemetryIngest.ts +8 -3
- package/Server/Services/AIInsightService.ts +132 -12
- package/Server/Services/AIRunService.ts +34 -0
- package/Server/Services/AIService.ts +17 -2
- package/Server/Services/AlertService.ts +38 -32
- package/Server/Services/AnalyticsDatabaseService.ts +8 -4
- package/Server/Services/DataSourceService.ts +200 -0
- package/Server/Services/HostService.ts +92 -0
- package/Server/Services/IncidentService.ts +45 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +49 -0
- package/Server/Services/MonitorStatusService.ts +166 -0
- package/Server/Services/OpenTelemetryIngestService.ts +255 -184
- package/Server/Services/RumSessionPinService.ts +7 -21
- package/Server/Services/StatusPageSubscriberService.ts +13 -0
- package/Server/Services/UserService.ts +280 -9
- package/Server/Static/Vendor/README.md +62 -0
- package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
- package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
- package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
- package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
- package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
- package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
- package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
- package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
- package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
- package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
- package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
- package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
- package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
- package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
- package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
- package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
- package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
- package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
- package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
- package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
- package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
- package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
- package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
- package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
- package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
- package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
- package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
- package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
- package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
- package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
- package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
- package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
- package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
- package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
- package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
- package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
- package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
- package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
- package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
- package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
- package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
- package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
- package/Server/Utils/DataSource/EgressGuard.ts +446 -0
- package/Server/Utils/DataSource/HttpFetch.ts +221 -0
- package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
- package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
- package/Server/Utils/DataSource/Types.ts +93 -0
- package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
- package/Server/Utils/InProcessMemo.ts +141 -0
- package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
- package/Server/Utils/Monitor/MonitorResource.ts +14 -0
- package/Server/Utils/Response.ts +12 -1
- package/Server/Utils/SSRFProtection.ts +237 -0
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
- package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
- package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
- package/Server/Utils/Telemetry/Telemetry.ts +112 -1
- package/Server/Utils/Telemetry.ts +104 -3
- package/Server/Utils/VendorAssets.ts +165 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
- package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
- package/Server/Views/Partials/Head.ejs +21 -7
- package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
- package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
- package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
- package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
- package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
- package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
- package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
- package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
- package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
- package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
- package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
- package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
- package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
- package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
- package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
- package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
- package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
- package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
- package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
- package/Tests/Server/Services/AIInsightService.test.ts +266 -11
- package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
- package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
- package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
- package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
- package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
- package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
- package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
- package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
- package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
- package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
- package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
- package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
- package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
- package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
- package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
- package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
- package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
- package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
- package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
- package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
- package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
- package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
- package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
- package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
- package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
- package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
- package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
- package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
- package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
- package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
- package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
- package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
- package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
- package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
- package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
- package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
- package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
- package/Tests/Server/Utils/Telemetry.test.ts +87 -0
- package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
- package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
- package/Tests/Server/Views/OfflineRender.test.ts +297 -0
- package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
- package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
- package/Tests/Types/Password.test.ts +363 -0
- package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
- package/Tests/UI/Components/Modal.test.tsx +281 -1
- package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/Utils/Analytics.test.ts +23 -0
- package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
- package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
- package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
- package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
- package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
- package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
- package/Types/AI/AIInsightEvidence.ts +6 -0
- package/Types/Analytics/RevenueEvent.ts +31 -0
- package/Types/Dashboard/DashboardComponentType.ts +31 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
- package/Types/DataSource/DataSourceLimits.ts +62 -0
- package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
- package/Types/DataSource/DataSourceTableResult.ts +38 -0
- package/Types/DataSource/DataSourceType.ts +213 -0
- package/Types/Date.ts +43 -3
- package/Types/Password.ts +64 -0
- package/Types/Permission.ts +46 -0
- package/Types/UserAuthenticationStatus.ts +34 -0
- package/UI/Components/Button/Button.tsx +1 -1
- package/UI/Components/ErrorBoundary.tsx +459 -108
- package/UI/Components/Icon/Icon.tsx +10 -9
- package/UI/Components/Modal/ConfirmModal.tsx +6 -1
- package/UI/Components/Modal/Modal.tsx +267 -35
- package/UI/Components/Modal/ModalFooter.tsx +6 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
- package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
- package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
- package/UI/Components/StatusPage/ResourceList.tsx +570 -0
- package/UI/Styles/Theme.css +18 -0
- package/UI/Utils/API/RequestOptions.ts +7 -0
- package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
- package/UI/Utils/TestDataSource.ts +61 -0
- package/UI/esbuild-config.js +45 -0
- package/Utils/Analytics.ts +15 -0
- package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
- package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
- package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
- package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
- package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
- package/Utils/Dashboard/Components/Index.ts +28 -0
- package/Utils/DataSource/DataSourceQueryText.ts +94 -0
- package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
- package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
- package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
- package/Utils/StatusPage/ResourceExplorer.ts +853 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
- package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +2 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
- package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +34 -4
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +119 -433
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/DataSourceAPI.js +173 -0
- package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +11 -1
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +94 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +27 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIInsightService.js +110 -10
- package/build/dist/Server/Services/AIInsightService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +34 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +16 -2
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +28 -35
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DataSourceService.js +159 -0
- package/build/dist/Server/Services/DataSourceService.js.map +1 -0
- package/build/dist/Server/Services/HostService.js +74 -0
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +35 -24
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusService.js +129 -0
- package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +7 -15
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +241 -10
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Types.js +2 -0
- package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
- package/build/dist/Server/Utils/InProcessMemo.js +113 -0
- package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +9 -1
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +192 -0
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +93 -6
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +121 -0
- package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
- package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceType.js +183 -0
- package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
- package/build/dist/Types/Date.js +38 -3
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Password.js +56 -0
- package/build/dist/Types/Password.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/UserAuthenticationStatus.js +2 -0
- package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
- package/build/dist/UI/Components/ErrorBoundary.js +388 -72
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +10 -4
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +178 -19
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/TestDataSource.js +39 -0
- package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
- package/build/dist/Utils/Analytics.js +4 -0
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
- package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
- package/jest.config.json +1 -0
- package/package.json +5 -1
- package/tsconfig.json +12 -10
|
@@ -9,6 +9,7 @@ import ExceptionInstanceService from "../../../../../Services/ExceptionInstanceS
|
|
|
9
9
|
import ServiceService from "../../../../../Services/ServiceService";
|
|
10
10
|
import QueryHelper from "../../../../../Types/Database/QueryHelper";
|
|
11
11
|
import { sanitizeExceptionMessage } from "../../../../Telemetry/ExceptionSanitizer";
|
|
12
|
+
import { EXCEPTION_LABEL_MESSAGE_MAX_LENGTH, buildExceptionLabel, } from "./ExceptionIdentity";
|
|
12
13
|
/*
|
|
13
14
|
* ExceptionSpike — an ESTABLISHED exception (first seen more than a day
|
|
14
15
|
* ago) whose recent hourly occurrence rate blew past its own 24-hour
|
|
@@ -47,7 +48,7 @@ export const EXCEPTION_SPIKE_HIGH_SEVERITY_MULTIPLIER = 10;
|
|
|
47
48
|
*/
|
|
48
49
|
export const EXCEPTION_SPIKE_CANDIDATE_LIMIT = 25;
|
|
49
50
|
// Titles must stay scannable in a list — truncate long exception messages.
|
|
50
|
-
export const EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH =
|
|
51
|
+
export const EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH = EXCEPTION_LABEL_MESSAGE_MAX_LENGTH;
|
|
51
52
|
export default class ExceptionSpikeDetector {
|
|
52
53
|
constructor() {
|
|
53
54
|
this.insightType = AIInsightType.ExceptionSpike;
|
|
@@ -75,23 +76,24 @@ export default class ExceptionSpikeDetector {
|
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
/*
|
|
78
|
-
* Human label for the exception: the type
|
|
79
|
-
*
|
|
79
|
+
* Human label for the exception: the type AND the message, because either
|
|
80
|
+
* one alone collides across findings (see ExceptionIdentity).
|
|
80
81
|
*/
|
|
81
82
|
static buildExceptionLabel(exceptionType, message) {
|
|
82
|
-
|
|
83
|
-
return exceptionType.trim();
|
|
84
|
-
}
|
|
85
|
-
const trimmedMessage = (message || "").trim();
|
|
86
|
-
if (trimmedMessage.length === 0) {
|
|
87
|
-
return "Unknown exception";
|
|
88
|
-
}
|
|
89
|
-
if (trimmedMessage.length <= EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH) {
|
|
90
|
-
return trimmedMessage;
|
|
91
|
-
}
|
|
92
|
-
return `${trimmedMessage.slice(0, EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH)}…`;
|
|
83
|
+
return buildExceptionLabel(exceptionType, message, EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH);
|
|
93
84
|
}
|
|
94
|
-
|
|
85
|
+
/*
|
|
86
|
+
* Stable dedupe key, keyed on the exception GROUP id (ingest dedupe unit).
|
|
87
|
+
*
|
|
88
|
+
* DELIBERATELY NOT the failure-mode key NewExceptionDetector files under.
|
|
89
|
+
* That detector's evidence is a Postgres column it can simply add up across
|
|
90
|
+
* the groups of one failure mode; a spike is a RATE, measured per ingest
|
|
91
|
+
* fingerprint in ClickHouse. Rolling several fingerprints into one insight
|
|
92
|
+
* would mean summing their windows and re-deciding the spike on the total —
|
|
93
|
+
* which changes what counts as a spike, not just how many rows it files.
|
|
94
|
+
* The title carries the type, the message and the multiplier, so sibling
|
|
95
|
+
* groups read as distinct rows rather than as copies.
|
|
96
|
+
*/
|
|
95
97
|
static buildFingerprint(telemetryExceptionId) {
|
|
96
98
|
return `exception-spike:${telemetryExceptionId}`;
|
|
97
99
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExceptionSpikeDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,SAAS,MAAM,gDAAgD,CAAC;AACvE,OAAO,SAAS,MAAM,gDAAgD,CAAC;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,aAAa,MAAM,0CAA0C,CAAC;AACrE,OAAO,iBAAiB,MAAM,8CAA8C,CAAC;AAG7E,OAAO,yBAAyB,MAAM,mDAAmD,CAAC;AAC1F,OAAO,wBAAwB,MAAM,kDAAkD,CAAC;AACxF,OAAO,cAAc,MAAM,wCAAwC,CAAC;AACpE,OAAO,WAAW,MAAM,2CAA2C,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"ExceptionSpikeDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,9 @@ import AIInsightSeverity from "../../../../../../Types/AI/AIInsightSeverity";
|
|
|
5
5
|
import TelemetryExceptionService from "../../../../../Services/TelemetryExceptionService";
|
|
6
6
|
import ServiceService from "../../../../../Services/ServiceService";
|
|
7
7
|
import QueryHelper from "../../../../../Types/Database/QueryHelper";
|
|
8
|
+
import logger from "../../../../Logger";
|
|
8
9
|
import { sanitizeExceptionMessage } from "../../../../Telemetry/ExceptionSanitizer";
|
|
10
|
+
import { EXCEPTION_LABEL_MESSAGE_MAX_LENGTH, buildExceptionFailureModeKey, buildExceptionLabel, } from "./ExceptionIdentity";
|
|
9
11
|
/*
|
|
10
12
|
* NewException — a brand-new failure mode in the code: a telemetry
|
|
11
13
|
* exception group whose FIRST occurrence is inside the lookback window and
|
|
@@ -13,6 +15,18 @@ import { sanitizeExceptionMessage } from "../../../../Telemetry/ExceptionSanitiz
|
|
|
13
15
|
* the exception groups table carries firstSeenAt and the lifetime
|
|
14
16
|
* occurrence count, so no ClickHouse scan is needed at all. Deterministic —
|
|
15
17
|
* no LLM anywhere in this detector.
|
|
18
|
+
*
|
|
19
|
+
* ONE INSIGHT PER FAILURE MODE, NOT PER EXCEPTION GROUP. Group identity at
|
|
20
|
+
* ingest hashes the normalized STACK TRACE alongside the type and message, so
|
|
21
|
+
* one logical failure raised from several call sites is several groups. This
|
|
22
|
+
* detector used to file one insight per group, which filed the same finding
|
|
23
|
+
* over and over — and because the title was the exceptionType alone, the rows
|
|
24
|
+
* were not merely duplicated but indistinguishable (a service whose
|
|
25
|
+
* instrumentation reports `exception.type = "401"` produced a wall of
|
|
26
|
+
* identical "New exception: 401 in api" rows). Candidates are therefore
|
|
27
|
+
* bucketed on the (entity, type, normalized message) failure mode, counts are
|
|
28
|
+
* summed across the member groups, and the insight is fingerprinted on that
|
|
29
|
+
* bucket — see ExceptionIdentity.
|
|
16
30
|
*/
|
|
17
31
|
/*
|
|
18
32
|
* Only exceptions born within this window count as "new". 24h matches the
|
|
@@ -24,30 +38,41 @@ export const NEW_EXCEPTION_LOOKBACK_HOURS = 24;
|
|
|
24
38
|
/*
|
|
25
39
|
* A single occurrence is noise (a deploy hiccup, a one-off bad request).
|
|
26
40
|
* Three occurrences means the failure path is being re-hit — worth a
|
|
27
|
-
* human's attention.
|
|
41
|
+
* human's attention. Applied per exception GROUP, before bucketing: a
|
|
42
|
+
* failure mode must have at least one group that is genuinely recurring,
|
|
43
|
+
* rather than qualifying by adding up single-occurrence stack variants.
|
|
28
44
|
*/
|
|
29
45
|
export const NEW_EXCEPTION_MIN_OCCURRENCE_COUNT = 3;
|
|
30
46
|
/*
|
|
31
47
|
* At 50+ occurrences inside its first day the exception is hammering a hot
|
|
32
|
-
* path — escalate to High so it sorts above the long tail.
|
|
48
|
+
* path — escalate to High so it sorts above the long tail. Measured on the
|
|
49
|
+
* failure mode's summed count, which is what the insight reports.
|
|
33
50
|
*/
|
|
34
51
|
export const NEW_EXCEPTION_HIGH_SEVERITY_OCCURRENCE_COUNT = 50;
|
|
35
52
|
/*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
53
|
+
* How many exception GROUPS one tick reads. Higher than the candidate cap
|
|
54
|
+
* because groups collapse into failure modes: a single noisy throw site can
|
|
55
|
+
* easily own dozens of stack-trace variants, and reading only 25 of them
|
|
56
|
+
* would let one loud failure mode crowd every other one out of the tick. It
|
|
57
|
+
* is one indexed Postgres query either way.
|
|
58
|
+
*/
|
|
59
|
+
export const NEW_EXCEPTION_GROUP_SCAN_LIMIT = 100;
|
|
60
|
+
/*
|
|
61
|
+
* Upper bound on candidates per scan tick, applied AFTER bucketing — a
|
|
62
|
+
* project melting down does not need 500 insights, and the scanner
|
|
38
63
|
* additionally caps new insights per tick.
|
|
39
64
|
*/
|
|
40
65
|
export const NEW_EXCEPTION_CANDIDATE_LIMIT = 25;
|
|
41
66
|
// Titles must stay scannable in a list — truncate long exception messages.
|
|
42
|
-
export const NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH =
|
|
67
|
+
export const NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH = EXCEPTION_LABEL_MESSAGE_MAX_LENGTH;
|
|
43
68
|
export default class NewExceptionDetector {
|
|
44
69
|
constructor() {
|
|
45
70
|
this.insightType = AIInsightType.NewException;
|
|
46
71
|
}
|
|
47
72
|
/*
|
|
48
|
-
* Pure decision: does
|
|
49
|
-
*
|
|
50
|
-
*
|
|
73
|
+
* Pure decision: does an occurrence count qualify, and how urgent is it.
|
|
74
|
+
* The query already filters on the minimum count — this re-check keeps the
|
|
75
|
+
* rule in one unit-testable place.
|
|
51
76
|
*/
|
|
52
77
|
static evaluateNewException(occurrenceCount) {
|
|
53
78
|
return {
|
|
@@ -58,29 +83,20 @@ export default class NewExceptionDetector {
|
|
|
58
83
|
};
|
|
59
84
|
}
|
|
60
85
|
/*
|
|
61
|
-
* Human label for the exception: the type
|
|
62
|
-
*
|
|
86
|
+
* Human label for the exception: the type AND the message, because either
|
|
87
|
+
* one alone collides across findings (see ExceptionIdentity).
|
|
63
88
|
*/
|
|
64
89
|
static buildExceptionLabel(exceptionType, message) {
|
|
65
|
-
|
|
66
|
-
return exceptionType.trim();
|
|
67
|
-
}
|
|
68
|
-
const trimmedMessage = (message || "").trim();
|
|
69
|
-
if (trimmedMessage.length === 0) {
|
|
70
|
-
return "Unknown exception";
|
|
71
|
-
}
|
|
72
|
-
if (trimmedMessage.length <= NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH) {
|
|
73
|
-
return trimmedMessage;
|
|
74
|
-
}
|
|
75
|
-
return `${trimmedMessage.slice(0, NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH)}…`;
|
|
90
|
+
return buildExceptionLabel(exceptionType, message, NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH);
|
|
76
91
|
}
|
|
77
92
|
/*
|
|
78
|
-
* Stable dedupe key. Keyed on the
|
|
79
|
-
*
|
|
80
|
-
*
|
|
93
|
+
* Stable dedupe key. Keyed on the FAILURE MODE (entity + exception type +
|
|
94
|
+
* normalized message), never on the exception group id: group identity
|
|
95
|
+
* includes the stack trace, so one failure raised from several call sites
|
|
96
|
+
* would otherwise file one insight per call site.
|
|
81
97
|
*/
|
|
82
|
-
static buildFingerprint(
|
|
83
|
-
return `new-exception:${
|
|
98
|
+
static buildFingerprint(failureModeKey) {
|
|
99
|
+
return `new-exception:${failureModeKey}`;
|
|
84
100
|
}
|
|
85
101
|
async detect(context) {
|
|
86
102
|
const firstSeenSince = OneUptimeDate.addRemoveHours(context.now, -1 * NEW_EXCEPTION_LOOKBACK_HOURS);
|
|
@@ -94,6 +110,13 @@ export default class NewExceptionDetector {
|
|
|
94
110
|
/*
|
|
95
111
|
* Root read with an explicit projectId in the query — the scanner is a
|
|
96
112
|
* server-side worker (monitor-worker precedent), never a user ACL.
|
|
113
|
+
*
|
|
114
|
+
* firstSeenAt is a deterministic tie-break on the LIMIT boundary:
|
|
115
|
+
* occuranceCount is incremented on every ingested event, so the long
|
|
116
|
+
* tail of a noisy endpoint sits densely tied right at the cut and an
|
|
117
|
+
* untie-broken ORDER BY hands back an arbitrary, shifting subset each
|
|
118
|
+
* tick. Bucketing already keeps that churn from filing duplicates; the
|
|
119
|
+
* tie-break keeps the tick itself reproducible.
|
|
97
120
|
*/
|
|
98
121
|
const exceptions = await TelemetryExceptionService.findBy({
|
|
99
122
|
query: query,
|
|
@@ -107,79 +130,180 @@ export default class NewExceptionDetector {
|
|
|
107
130
|
},
|
|
108
131
|
sort: {
|
|
109
132
|
occuranceCount: SortOrder.Descending,
|
|
133
|
+
firstSeenAt: SortOrder.Ascending,
|
|
110
134
|
},
|
|
111
|
-
limit:
|
|
135
|
+
limit: NEW_EXCEPTION_GROUP_SCAN_LIMIT,
|
|
112
136
|
skip: 0,
|
|
113
137
|
props: { isRoot: true },
|
|
114
138
|
});
|
|
139
|
+
const failureModes = NewExceptionDetector.bucketIntoFailureModes(exceptions);
|
|
115
140
|
const candidates = [];
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
// Service names are resolved once per entity, not once per group.
|
|
142
|
+
const serviceNameCache = new Map();
|
|
143
|
+
for (const failureMode of failureModes) {
|
|
144
|
+
const decision = NewExceptionDetector.evaluateNewException(failureMode.totalOccurrenceCount);
|
|
145
|
+
if (!decision.qualifies) {
|
|
120
146
|
continue;
|
|
121
147
|
}
|
|
122
|
-
const serviceName = await this.resolveServiceName(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* interpolated user data (IDs, emails, domains) rides along. The raw
|
|
127
|
-
* message stays on the exception row for the dashboard.
|
|
128
|
-
*/
|
|
129
|
-
const safeMessage = sanitizeExceptionMessage(exception.message || "");
|
|
130
|
-
const label = NewExceptionDetector.buildExceptionLabel(exception.exceptionType, safeMessage);
|
|
131
|
-
const firstSeenAtIso = exception.firstSeenAt
|
|
132
|
-
? exception.firstSeenAt.toISOString()
|
|
148
|
+
const serviceName = await this.resolveServiceName(failureMode.representative.primaryEntityId, serviceNameCache);
|
|
149
|
+
const label = NewExceptionDetector.buildExceptionLabel(failureMode.representative.exceptionType, failureMode.safeMessage);
|
|
150
|
+
const firstSeenAtIso = failureMode.firstSeenAt
|
|
151
|
+
? failureMode.firstSeenAt.toISOString()
|
|
133
152
|
: undefined;
|
|
134
153
|
const detailLines = [
|
|
135
154
|
"**New exception detected**",
|
|
136
155
|
"",
|
|
137
156
|
`- Exception: \`${label}\``,
|
|
138
157
|
];
|
|
139
|
-
if (safeMessage) {
|
|
140
|
-
detailLines.push(`- Message: ${safeMessage}`);
|
|
158
|
+
if (failureMode.safeMessage) {
|
|
159
|
+
detailLines.push(`- Message: ${failureMode.safeMessage}`);
|
|
141
160
|
}
|
|
142
161
|
if (serviceName) {
|
|
143
162
|
detailLines.push(`- Service: ${serviceName}`);
|
|
144
163
|
}
|
|
145
|
-
detailLines.push(`- First seen: ${firstSeenAtIso || "unknown"} (within the last ${NEW_EXCEPTION_LOOKBACK_HOURS}h)`, `- Occurrences so far: ${
|
|
164
|
+
detailLines.push(`- First seen: ${firstSeenAtIso || "unknown"} (within the last ${NEW_EXCEPTION_LOOKBACK_HOURS}h)`, `- Occurrences so far: ${failureMode.totalOccurrenceCount}`);
|
|
165
|
+
if (failureMode.groupCount > 1) {
|
|
166
|
+
detailLines.push(`- Raised from ${failureMode.groupCount} distinct stack traces (same exception type and message — counted together as one failure mode)`);
|
|
167
|
+
}
|
|
146
168
|
candidates.push({
|
|
147
169
|
insightType: AIInsightType.NewException,
|
|
148
|
-
fingerprint: NewExceptionDetector.buildFingerprint(
|
|
170
|
+
fingerprint: NewExceptionDetector.buildFingerprint(failureMode.failureModeKey),
|
|
149
171
|
title: `New exception: ${label}${serviceName ? ` in ${serviceName}` : ""}`,
|
|
150
172
|
detailMarkdown: detailLines.join("\n"),
|
|
151
173
|
severity: decision.severity,
|
|
152
174
|
serviceName: serviceName || undefined,
|
|
153
|
-
telemetryServiceId: serviceName
|
|
154
|
-
|
|
175
|
+
telemetryServiceId: serviceName
|
|
176
|
+
? failureMode.representative.primaryEntityId
|
|
177
|
+
: undefined,
|
|
178
|
+
telemetryExceptionId: failureMode.representativeExceptionId,
|
|
155
179
|
evidence: {
|
|
156
180
|
exception: {
|
|
157
|
-
exceptionMessage: safeMessage,
|
|
158
|
-
exceptionType:
|
|
159
|
-
totalOccurrenceCount:
|
|
181
|
+
exceptionMessage: failureMode.safeMessage,
|
|
182
|
+
exceptionType: failureMode.representative.exceptionType,
|
|
183
|
+
totalOccurrenceCount: failureMode.totalOccurrenceCount,
|
|
184
|
+
distinctExceptionGroupCount: failureMode.groupCount,
|
|
160
185
|
firstSeenAt: firstSeenAtIso,
|
|
161
186
|
},
|
|
162
187
|
},
|
|
163
188
|
});
|
|
189
|
+
if (candidates.length >= NEW_EXCEPTION_CANDIDATE_LIMIT) {
|
|
190
|
+
// No silent caps — say what this tick left on the floor.
|
|
191
|
+
if (failureModes.length > candidates.length) {
|
|
192
|
+
logger.debug(`AI Insights: NewException capped at ${NEW_EXCEPTION_CANDIDATE_LIMIT} candidates for project ${context.projectId.toString()} — ${failureModes.length - candidates.length} further failure mode(s) this tick were not emitted. They re-surface on later ticks while their exceptions stay inside the ${NEW_EXCEPTION_LOOKBACK_HOURS}h window.`);
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
164
196
|
}
|
|
165
197
|
return candidates;
|
|
166
198
|
}
|
|
199
|
+
/*
|
|
200
|
+
* Roll the tick's exception groups up into failure modes, loudest first.
|
|
201
|
+
*
|
|
202
|
+
* The representative is the group with the highest lifetime occurrence
|
|
203
|
+
* count (ties broken by the earliest firstSeenAt, then by id, so the choice
|
|
204
|
+
* is deterministic rather than dependent on row order). It supplies the
|
|
205
|
+
* label and the exception the insight links to — but NOT the fingerprint,
|
|
206
|
+
* which is the bucket key, so a representative that changes as counts move
|
|
207
|
+
* can never file a second insight for the same failure mode.
|
|
208
|
+
*/
|
|
209
|
+
static bucketIntoFailureModes(exceptions) {
|
|
210
|
+
const buckets = new Map();
|
|
211
|
+
for (const exception of exceptions) {
|
|
212
|
+
const exceptionId = exception.id || undefined;
|
|
213
|
+
if (!exceptionId) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const failureModeKey = buildExceptionFailureModeKey({
|
|
217
|
+
primaryEntityId: exception.primaryEntityId,
|
|
218
|
+
exceptionType: exception.exceptionType,
|
|
219
|
+
message: exception.message,
|
|
220
|
+
});
|
|
221
|
+
const occurrenceCount = exception.occuranceCount || 0;
|
|
222
|
+
const existing = buckets.get(failureModeKey);
|
|
223
|
+
if (!existing) {
|
|
224
|
+
buckets.set(failureModeKey, {
|
|
225
|
+
failureModeKey: failureModeKey,
|
|
226
|
+
representative: exception,
|
|
227
|
+
representativeExceptionId: exceptionId,
|
|
228
|
+
totalOccurrenceCount: occurrenceCount,
|
|
229
|
+
groupCount: 1,
|
|
230
|
+
firstSeenAt: exception.firstSeenAt,
|
|
231
|
+
/*
|
|
232
|
+
* The message flows into the insight title/detail/evidence, and
|
|
233
|
+
* from there into the triage LLM prompt — sanitize it once here so
|
|
234
|
+
* no interpolated user data (IDs, emails, domains) rides along. The
|
|
235
|
+
* raw message stays on the exception row for the dashboard.
|
|
236
|
+
*/
|
|
237
|
+
safeMessage: sanitizeExceptionMessage(exception.message || ""),
|
|
238
|
+
});
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
existing.totalOccurrenceCount += occurrenceCount;
|
|
242
|
+
existing.groupCount++;
|
|
243
|
+
if (exception.firstSeenAt &&
|
|
244
|
+
(!existing.firstSeenAt || exception.firstSeenAt < existing.firstSeenAt)) {
|
|
245
|
+
existing.firstSeenAt = exception.firstSeenAt;
|
|
246
|
+
}
|
|
247
|
+
if (NewExceptionDetector.isBetterRepresentative(exception, existing.representative)) {
|
|
248
|
+
existing.representative = exception;
|
|
249
|
+
existing.representativeExceptionId = exceptionId;
|
|
250
|
+
existing.safeMessage = sanitizeExceptionMessage(exception.message || "");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/*
|
|
254
|
+
* Loudest first, ties broken on the key — the candidate cap cuts this
|
|
255
|
+
* list, so the order decides what a tick emits and it must not depend on
|
|
256
|
+
* the arbitrary order rows came back in.
|
|
257
|
+
*/
|
|
258
|
+
return Array.from(buckets.values()).sort((a, b) => {
|
|
259
|
+
if (a.totalOccurrenceCount !== b.totalOccurrenceCount) {
|
|
260
|
+
return b.totalOccurrenceCount - a.totalOccurrenceCount;
|
|
261
|
+
}
|
|
262
|
+
return a.failureModeKey < b.failureModeKey ? -1 : 1;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
// Loudest wins; ties go to the older group, then to the lower id.
|
|
266
|
+
static isBetterRepresentative(candidate, current) {
|
|
267
|
+
var _a, _b;
|
|
268
|
+
const candidateCount = candidate.occuranceCount || 0;
|
|
269
|
+
const currentCount = current.occuranceCount || 0;
|
|
270
|
+
if (candidateCount !== currentCount) {
|
|
271
|
+
return candidateCount > currentCount;
|
|
272
|
+
}
|
|
273
|
+
if (candidate.firstSeenAt && current.firstSeenAt) {
|
|
274
|
+
const candidateTime = candidate.firstSeenAt.getTime();
|
|
275
|
+
const currentTime = current.firstSeenAt.getTime();
|
|
276
|
+
if (candidateTime !== currentTime) {
|
|
277
|
+
return candidateTime < currentTime;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return (((_a = candidate.id) === null || _a === void 0 ? void 0 : _a.toString()) || "") < (((_b = current.id) === null || _b === void 0 ? void 0 : _b.toString()) || "");
|
|
281
|
+
}
|
|
167
282
|
/*
|
|
168
283
|
* Best-effort service attribution: primaryEntityId is polymorphic
|
|
169
284
|
* (Service/Host/DockerHost/...), and findOneById simply returns null for
|
|
170
285
|
* the non-Service kinds (AIInvestigationAPI precedent) — the insight then
|
|
171
|
-
* ships without a service name.
|
|
286
|
+
* ships without a service name. Cached per tick: a project's exceptions
|
|
287
|
+
* cluster on a handful of services, and the lookup is the only per-
|
|
288
|
+
* candidate IO left in this detector.
|
|
172
289
|
*/
|
|
173
|
-
async resolveServiceName(primaryEntityId) {
|
|
290
|
+
async resolveServiceName(primaryEntityId, cache) {
|
|
174
291
|
if (!primaryEntityId) {
|
|
175
292
|
return null;
|
|
176
293
|
}
|
|
294
|
+
const cacheKey = primaryEntityId.toString();
|
|
295
|
+
const cached = cache.get(cacheKey);
|
|
296
|
+
if (cached !== undefined) {
|
|
297
|
+
return cached;
|
|
298
|
+
}
|
|
177
299
|
const service = await ServiceService.findOneById({
|
|
178
300
|
id: primaryEntityId,
|
|
179
301
|
select: { name: true },
|
|
180
302
|
props: { isRoot: true },
|
|
181
303
|
});
|
|
182
|
-
|
|
304
|
+
const serviceName = (service === null || service === void 0 ? void 0 : service.name) || null;
|
|
305
|
+
cache.set(cacheKey, serviceName);
|
|
306
|
+
return serviceName;
|
|
183
307
|
}
|
|
184
308
|
}
|
|
185
309
|
//# sourceMappingURL=NewExceptionDetector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewExceptionDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,SAAS,MAAM,gDAAgD,CAAC;AAEvE,OAAO,aAAa,MAAM,0CAA0C,CAAC;AACrE,OAAO,iBAAiB,MAAM,8CAA8C,CAAC;AAG7E,OAAO,yBAAyB,MAAM,mDAAmD,CAAC;AAC1F,OAAO,cAAc,MAAM,wCAAwC,CAAC;AACpE,OAAO,WAAW,MAAM,2CAA2C,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"NewExceptionDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,SAAS,MAAM,gDAAgD,CAAC;AAEvE,OAAO,aAAa,MAAM,0CAA0C,CAAC;AACrE,OAAO,iBAAiB,MAAM,8CAA8C,CAAC;AAG7E,OAAO,yBAAyB,MAAM,mDAAmD,CAAC;AAC1F,OAAO,cAAc,MAAM,wCAAwC,CAAC;AACpE,OAAO,WAAW,MAAM,2CAA2C,CAAC;AACpE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EACL,kCAAkC,EAClC,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAO7B;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAW,EAAE,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAW,CAAC,CAAC;AAE5D;;;;GAIG;AACH,MAAM,CAAC,MAAM,4CAA4C,GAAW,EAAE,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAW,GAAG,CAAC;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAW,EAAE,CAAC;AAExD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,sCAAsC,GACjD,kCAAkC,CAAC;AA4BrC,MAAM,CAAC,OAAO,OAAO,oBAAoB;IAAzC;QACS,gBAAW,GAAkB,aAAa,CAAC,YAAY,CAAC;IA2UjE,CAAC;IAzUC;;;;OAIG;IACI,MAAM,CAAC,oBAAoB,CAChC,eAAuB;QAEvB,OAAO;YACL,SAAS,EAAE,eAAe,IAAI,kCAAkC;YAChE,QAAQ,EACN,eAAe,IAAI,4CAA4C;gBAC7D,CAAC,CAAC,iBAAiB,CAAC,IAAI;gBACxB,CAAC,CAAC,iBAAiB,CAAC,MAAM;SAC/B,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,mBAAmB,CAC/B,aAAiC,EACjC,OAA2B;QAE3B,OAAO,mBAAmB,CACxB,aAAa,EACb,OAAO,EACP,sCAAsC,CACvC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,gBAAgB,CAAC,cAAsB;QACnD,OAAO,iBAAiB,cAAc,EAAE,CAAC;IAC3C,CAAC;IAEM,KAAK,CAAC,MAAM,CACjB,OAA2B;QAE3B,MAAM,cAAc,GAAS,aAAa,CAAC,cAAc,CACvD,OAAO,CAAC,GAAG,EACX,CAAC,CAAC,GAAG,4BAA4B,CAClC,CAAC;QAEF,MAAM,KAAK,GAAe;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC;YAC3D,UAAU,EAAE,KAAK;YACjB,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,WAAW,CAAC,kBAAkB,CAC5C,kCAAkC,CACnC;SACF,CAAC;QAEF;;;;;;;;;;WAUG;QACH,MAAM,UAAU,GACd,MAAM,yBAAyB,CAAC,MAAM,CAAC;YACrC,KAAK,EAAE,KAAc;YACrB,MAAM,EAAE;gBACN,GAAG,EAAE,IAAI;gBACT,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,IAAI;gBACnB,cAAc,EAAE,IAAI;gBACpB,WAAW,EAAE,IAAI;gBACjB,eAAe,EAAE,IAAI;aACtB;YACD,IAAI,EAAE;gBACJ,cAAc,EAAE,SAAS,CAAC,UAAU;gBACpC,WAAW,EAAE,SAAS,CAAC,SAAS;aACjC;YACD,KAAK,EAAE,8BAA8B;YACrC,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SACxB,CAAC,CAAC;QAEL,MAAM,YAAY,GAChB,oBAAoB,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QAE1D,MAAM,UAAU,GAA4B,EAAE,CAAC;QAE/C,kEAAkE;QAClE,MAAM,gBAAgB,GAA+B,IAAI,GAAG,EAAE,CAAC;QAE/D,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,MAAM,QAAQ,GACZ,oBAAoB,CAAC,oBAAoB,CACvC,WAAW,CAAC,oBAAoB,CACjC,CAAC;YAEJ,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAkB,MAAM,IAAI,CAAC,kBAAkB,CAC9D,WAAW,CAAC,cAAc,CAAC,eAAe,EAC1C,gBAAgB,CACjB,CAAC;YAEF,MAAM,KAAK,GAAW,oBAAoB,CAAC,mBAAmB,CAC5D,WAAW,CAAC,cAAc,CAAC,aAAa,EACxC,WAAW,CAAC,WAAW,CACxB,CAAC;YAEF,MAAM,cAAc,GAAuB,WAAW,CAAC,WAAW;gBAChE,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,WAAW,EAAE;gBACvC,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,WAAW,GAAkB;gBACjC,4BAA4B;gBAC5B,EAAE;gBACF,kBAAkB,KAAK,IAAI;aAC5B,CAAC;YACF,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;gBAC5B,WAAW,CAAC,IAAI,CAAC,cAAc,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,IAAI,CAAC,cAAc,WAAW,EAAE,CAAC,CAAC;YAChD,CAAC;YACD,WAAW,CAAC,IAAI,CACd,iBAAiB,cAAc,IAAI,SAAS,qBAAqB,4BAA4B,IAAI,EACjG,yBAAyB,WAAW,CAAC,oBAAoB,EAAE,CAC5D,CAAC;YACF,IAAI,WAAW,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC/B,WAAW,CAAC,IAAI,CACd,iBAAiB,WAAW,CAAC,UAAU,iGAAiG,CACzI,CAAC;YACJ,CAAC;YAED,UAAU,CAAC,IAAI,CAAC;gBACd,WAAW,EAAE,aAAa,CAAC,YAAY;gBACvC,WAAW,EAAE,oBAAoB,CAAC,gBAAgB,CAChD,WAAW,CAAC,cAAc,CAC3B;gBACD,KAAK,EAAE,kBAAkB,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC1E,cAAc,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;gBACtC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,WAAW,EAAE,WAAW,IAAI,SAAS;gBACrC,kBAAkB,EAAE,WAAW;oBAC7B,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe;oBAC5C,CAAC,CAAC,SAAS;gBACb,oBAAoB,EAAE,WAAW,CAAC,yBAAyB;gBAC3D,QAAQ,EAAE;oBACR,SAAS,EAAE;wBACT,gBAAgB,EAAE,WAAW,CAAC,WAAW;wBACzC,aAAa,EAAE,WAAW,CAAC,cAAc,CAAC,aAAa;wBACvD,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;wBACtD,2BAA2B,EAAE,WAAW,CAAC,UAAU;wBACnD,WAAW,EAAE,cAAc;qBAC5B;iBACF;aACF,CAAC,CAAC;YAEH,IAAI,UAAU,CAAC,MAAM,IAAI,6BAA6B,EAAE,CAAC;gBACvD,yDAAyD;gBACzD,IAAI,YAAY,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;oBAC5C,MAAM,CAAC,KAAK,CACV,uCAAuC,6BAA6B,2BAA2B,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,MACzH,YAAY,CAAC,MAAM,GAAG,UAAU,CAAC,MACnC,8HAA8H,4BAA4B,WAAW,CACtK,CAAC;gBACJ,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;;;;;;OASG;IACI,MAAM,CAAC,sBAAsB,CAClC,UAAqC;QAErC,MAAM,OAAO,GAAyC,IAAI,GAAG,EAAE,CAAC;QAEhE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,WAAW,GAAyB,SAAS,CAAC,EAAE,IAAI,SAAS,CAAC;YAEpE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,SAAS;YACX,CAAC;YAED,MAAM,cAAc,GAAW,4BAA4B,CAAC;gBAC1D,eAAe,EAAE,SAAS,CAAC,eAAe;gBAC1C,aAAa,EAAE,SAAS,CAAC,aAAa;gBACtC,OAAO,EAAE,SAAS,CAAC,OAAO;aAC3B,CAAC,CAAC;YAEH,MAAM,eAAe,GAAW,SAAS,CAAC,cAAc,IAAI,CAAC,CAAC;YAC9D,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAE9B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;oBAC1B,cAAc,EAAE,cAAc;oBAC9B,cAAc,EAAE,SAAS;oBACzB,yBAAyB,EAAE,WAAW;oBACtC,oBAAoB,EAAE,eAAe;oBACrC,UAAU,EAAE,CAAC;oBACb,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC;;;;;uBAKG;oBACH,WAAW,EAAE,wBAAwB,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC;iBAC/D,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,QAAQ,CAAC,oBAAoB,IAAI,eAAe,CAAC;YACjD,QAAQ,CAAC,UAAU,EAAE,CAAC;YAEtB,IACE,SAAS,CAAC,WAAW;gBACrB,CAAC,CAAC,QAAQ,CAAC,WAAW,IAAI,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,EACvE,CAAC;gBACD,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;YAC/C,CAAC;YAED,IACE,oBAAoB,CAAC,sBAAsB,CACzC,SAAS,EACT,QAAQ,CAAC,cAAc,CACxB,EACD,CAAC;gBACD,QAAQ,CAAC,cAAc,GAAG,SAAS,CAAC;gBACpC,QAAQ,CAAC,yBAAyB,GAAG,WAAW,CAAC;gBACjD,QAAQ,CAAC,WAAW,GAAG,wBAAwB,CAC7C,SAAS,CAAC,OAAO,IAAI,EAAE,CACxB,CAAC;YACJ,CAAC;QACH,CAAC;QAED;;;;WAIG;QACH,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CACtC,CAAC,CAA0B,EAAE,CAA0B,EAAU,EAAE;YACjE,IAAI,CAAC,CAAC,oBAAoB,KAAK,CAAC,CAAC,oBAAoB,EAAE,CAAC;gBACtD,OAAO,CAAC,CAAC,oBAAoB,GAAG,CAAC,CAAC,oBAAoB,CAAC;YACzD,CAAC;YACD,OAAO,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CACF,CAAC;IACJ,CAAC;IAED,kEAAkE;IAC1D,MAAM,CAAC,sBAAsB,CACnC,SAA6B,EAC7B,OAA2B;;QAE3B,MAAM,cAAc,GAAW,SAAS,CAAC,cAAc,IAAI,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAW,OAAO,CAAC,cAAc,IAAI,CAAC,CAAC;QAEzD,IAAI,cAAc,KAAK,YAAY,EAAE,CAAC;YACpC,OAAO,cAAc,GAAG,YAAY,CAAC;QACvC,CAAC;QAED,IAAI,SAAS,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACjD,MAAM,aAAa,GAAW,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YAC9D,MAAM,WAAW,GAAW,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YAC1D,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;gBAClC,OAAO,aAAa,GAAG,WAAW,CAAC;YACrC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,CAAA,MAAA,SAAS,CAAC,EAAE,0CAAE,QAAQ,EAAE,KAAI,EAAE,CAAC,GAAG,CAAC,CAAA,MAAA,OAAO,CAAC,EAAE,0CAAE,QAAQ,EAAE,KAAI,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,kBAAkB,CAC9B,eAAqC,EACrC,KAAiC;QAEjC,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAW,eAAe,CAAC,QAAQ,EAAE,CAAC;QACpD,MAAM,MAAM,GAA8B,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,OAAO,GAAmB,MAAM,cAAc,CAAC,WAAW,CAAC;YAC/D,EAAE,EAAE,eAAe;YACnB,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACtB,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SACxB,CAAC,CAAC;QAEH,MAAM,WAAW,GAAkB,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,KAAI,IAAI,CAAC;QACzD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACjC,OAAO,WAAW,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -35,10 +35,28 @@ export const MAX_NEW_INSIGHTS_PER_PROJECT_PER_SCAN = 10;
|
|
|
35
35
|
* G11 noise posture: a human dismissal is the strongest precision signal we
|
|
36
36
|
* have, so a finding with the same fingerprint stays suppressed for this
|
|
37
37
|
* many days after the dismissal instead of reappearing on the next tick.
|
|
38
|
-
* After the cooldown (or after a Resolved insight's signal returns) a fresh
|
|
39
|
-
* insight is warranted — a resolved issue that reappears is a regression.
|
|
40
38
|
*/
|
|
41
39
|
export const DISMISSED_COOLDOWN_DAYS = 7;
|
|
40
|
+
/*
|
|
41
|
+
* The same idea for the other human terminal state, with a much shorter
|
|
42
|
+
* clock: a resolved issue that comes back IS a regression worth re-filing,
|
|
43
|
+
* but it has to actually come back first.
|
|
44
|
+
*
|
|
45
|
+
* WITHOUT THIS, RESOLVE DID NOT STICK. Detectors emit on a standing
|
|
46
|
+
* condition, not on an event — NewException re-emits an unchanged candidate
|
|
47
|
+
* on all ~96 ticks of the 24h window after the exception's firstSeenAt, and
|
|
48
|
+
* resolving an insight changes nothing the detector looks at. So a Resolved
|
|
49
|
+
* row (terminal, therefore never refreshed) fell straight through to CREATE
|
|
50
|
+
* and a byte-identical insight reappeared within 15 minutes, complete with
|
|
51
|
+
* its own triage LLM run. Resolving again just minted another one.
|
|
52
|
+
*
|
|
53
|
+
* 24 hours is chosen to cover NEW_EXCEPTION_LOOKBACK_HOURS: it outlasts the
|
|
54
|
+
* window in which a NewException candidate is re-emitted from the same
|
|
55
|
+
* evidence, so that finding stays closed, while the standing-condition
|
|
56
|
+
* detectors (spikes, drift) can still re-file a day later if their signal
|
|
57
|
+
* genuinely returns.
|
|
58
|
+
*/
|
|
59
|
+
export const RESOLVED_COOLDOWN_HOURS = 24;
|
|
42
60
|
/*
|
|
43
61
|
* Column-safety clamps: DatabaseService validates string columns against the
|
|
44
62
|
* model's declared lengths and THROWS on overflow, and detectors embed raw
|
|
@@ -63,8 +81,8 @@ export default class InsightStore {
|
|
|
63
81
|
* - none → CREATE (subject to the per-scan cap)
|
|
64
82
|
* - non-terminal → REFRESH (never touches status)
|
|
65
83
|
* - Dismissed within the cooldown → suppress
|
|
66
|
-
* -
|
|
67
|
-
*
|
|
84
|
+
* - Resolved within the cooldown → suppress
|
|
85
|
+
* - either, past its cooldown → CREATE (regression / recurrence)
|
|
68
86
|
* All access is root-props: the scanner is a system actor with explicit
|
|
69
87
|
* projectId scoping, not a per-user ACL consumer.
|
|
70
88
|
*/
|
|
@@ -107,6 +125,8 @@ export default class InsightStore {
|
|
|
107
125
|
status: true,
|
|
108
126
|
occurrenceCount: true,
|
|
109
127
|
humanVerdictAt: true,
|
|
128
|
+
// The cooldown fallback when no verdict was ever stamped.
|
|
129
|
+
lastSeenAt: true,
|
|
110
130
|
},
|
|
111
131
|
sort: { createdAt: SortOrder.Descending },
|
|
112
132
|
props: { isRoot: true },
|
|
@@ -127,6 +147,14 @@ export default class InsightStore {
|
|
|
127
147
|
lastSeenAt: data.now,
|
|
128
148
|
occurrenceCount: (existing.occurrenceCount || 1) + 1,
|
|
129
149
|
severity: candidate.severity,
|
|
150
|
+
/*
|
|
151
|
+
* The title is refreshed with the rest of the picture, not
|
|
152
|
+
* frozen at creation. Detectors put live numbers in it (a spike
|
|
153
|
+
* multiplier, a latency factor) and the label itself sharpens as
|
|
154
|
+
* more of the failure is observed — a row left showing "at 5.2x"
|
|
155
|
+
* beside a High severity and a 12x detail body reads as a bug.
|
|
156
|
+
*/
|
|
157
|
+
title: this.clampToColumn(candidate.title, INSIGHT_TITLE_MAX_LENGTH),
|
|
130
158
|
detailMarkdown: candidate.detailMarkdown,
|
|
131
159
|
evidence: candidate.evidence,
|
|
132
160
|
},
|
|
@@ -135,22 +163,43 @@ export default class InsightStore {
|
|
|
135
163
|
result.refreshed++;
|
|
136
164
|
continue;
|
|
137
165
|
}
|
|
138
|
-
if (existing &&
|
|
166
|
+
if (existing &&
|
|
167
|
+
existing.status &&
|
|
168
|
+
AIInsightStatusHelper.isTerminalStatus(existing.status)) {
|
|
169
|
+
/*
|
|
170
|
+
* Both human terminal states get a cooldown, measured from the
|
|
171
|
+
* human's action and inclusive at the boundary (a cooldown exactly
|
|
172
|
+
* elapsed still suppresses). They differ only in length: a
|
|
173
|
+
* dismissal says "this is not worth my time" (7 days), a resolve
|
|
174
|
+
* says "handled" (24 hours — long enough that the detector stops
|
|
175
|
+
* re-emitting the very evidence the human just closed).
|
|
176
|
+
*/
|
|
177
|
+
const isDismissed = existing.status === AIInsightStatus.Dismissed;
|
|
178
|
+
const cooldownMs = isDismissed
|
|
179
|
+
? OneUptimeDate.getMillisecondsInDays(DISMISSED_COOLDOWN_DAYS)
|
|
180
|
+
: OneUptimeDate.getMillisecondsInHours(RESOLVED_COOLDOWN_HOURS);
|
|
139
181
|
/*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
182
|
+
* humanVerdictAt is the moment the human acted. It can be missing
|
|
183
|
+
* (defensive) and, on a Confirm-then-Resolve, it holds the CONFIRM
|
|
184
|
+
* time — resolveInsight leaves an existing verdict alone. lastSeenAt
|
|
185
|
+
* is the fallback: refreshes stop the moment a row goes terminal, so
|
|
186
|
+
* it is pinned to the last tick before the human closed it, which is
|
|
187
|
+
* never later than the close. Neither available → suppress; a
|
|
188
|
+
* terminal row we cannot date must not be re-filed every 15 minutes
|
|
189
|
+
* (G11 noise posture: when in doubt, stay quiet).
|
|
145
190
|
*/
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
OneUptimeDate.fromString(existing.
|
|
150
|
-
|
|
191
|
+
const closedAt = existing.humanVerdictAt
|
|
192
|
+
? OneUptimeDate.fromString(existing.humanVerdictAt)
|
|
193
|
+
: existing.lastSeenAt
|
|
194
|
+
? OneUptimeDate.fromString(existing.lastSeenAt)
|
|
195
|
+
: undefined;
|
|
196
|
+
const withinCooldown = closedAt
|
|
197
|
+
? data.now.getTime() - closedAt.getTime() <= cooldownMs
|
|
151
198
|
: true;
|
|
152
199
|
if (withinCooldown) {
|
|
153
|
-
logger.debug(`AI Insights: suppressing candidate ${fingerprint} for project ${data.projectId.toString()} —
|
|
200
|
+
logger.debug(`AI Insights: suppressing candidate ${fingerprint} for project ${data.projectId.toString()} — ${isDismissed
|
|
201
|
+
? `dismissed by a human within the last ${DISMISSED_COOLDOWN_DAYS} days`
|
|
202
|
+
: `resolved by a human within the last ${RESOLVED_COOLDOWN_HOURS} hours`}.`);
|
|
154
203
|
result.suppressed++;
|
|
155
204
|
continue;
|
|
156
205
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InsightStore.js","sourceRoot":"","sources":["../../../../../../../Server/Utils/AI/SRE/Insights/InsightStore.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,aAAa,MAAM,2BAA2B,CAAC;AACtD,OAAO,YAAY,MAAM,4CAA4C,CAAC;AACtE,OAAO,SAAS,MAAM,6CAA6C,CAAC;AACpE,OAAO,SAAS,MAAM,gDAAgD,CAAC;AACvE,OAAO,eAAe,EAAE,EACtB,qBAAqB,GACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,gBAAgB,MAAM,uCAAuC,CAAC;AAErE,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,WAAW,MAAM,gCAAgC,CAAC;AAEzD;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAW,EAAE,CAAC;AAEhE
|
|
1
|
+
{"version":3,"file":"InsightStore.js","sourceRoot":"","sources":["../../../../../../../Server/Utils/AI/SRE/Insights/InsightStore.ts"],"names":[],"mappings":"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"}
|