import styled from '@emotion/styled'; import Feature from 'sentry/components/acl/feature'; import {Alert} from 'sentry/components/alert'; import {Breadcrumbs} from 'sentry/components/breadcrumbs'; import * as Layout from 'sentry/components/layouts/thirds'; import NoProjectMessage from 'sentry/components/noProjectMessage'; import {DatePageFilter} from 'sentry/components/organizations/datePageFilter'; import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter'; import PageFilterBar from 'sentry/components/organizations/pageFilterBar'; import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container'; import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {CurrencyUnit, DurationUnit, RateUnit} from 'sentry/utils/discover/fields'; import {MutableSearch} from 'sentry/utils/tokenizeSearch'; import useOrganization from 'sentry/utils/useOrganization'; import {normalizeUrl} from 'sentry/utils/withDomainRequired'; import { NumberOfPipelinesChart, PipelineDurationChart, TotalTokensUsedChart, } from 'sentry/views/aiMonitoring/aiMonitoringCharts'; import {PipelineSpansTable} from 'sentry/views/aiMonitoring/pipelineSpansTable'; import {MetricReadout} from 'sentry/views/performance/metricReadout'; import * as ModuleLayout from 'sentry/views/performance/moduleLayout'; import {useSpanMetrics} from 'sentry/views/starfish/queries/useDiscover'; import { SpanFunction, SpanMetricsField, type SpanMetricsQueryFilters, } from 'sentry/views/starfish/types'; function NoAccessComponent() { return ( {t("You don't have access to this feature")} ); } interface Props { params: { groupId: string; }; } export default function AiMonitoringPage({params}: Props) { const organization = useOrganization(); const {groupId} = params; const filters: SpanMetricsQueryFilters = { 'span.group': groupId, 'span.category': 'ai.pipeline', }; const {data, isLoading: areSpanMetricsLoading} = useSpanMetrics( { search: MutableSearch.fromQueryObject(filters), fields: [ SpanMetricsField.SPAN_OP, SpanMetricsField.SPAN_DESCRIPTION, 'count()', `${SpanFunction.SPM}()`, `avg(${SpanMetricsField.SPAN_DURATION})`, ], enabled: Boolean(groupId), }, 'api.ai-pipelines.view' ); const spanMetrics = data[0] ?? {}; const {data: totalTokenData, isLoading: isTotalTokenDataLoading} = useSpanMetrics( { search: MutableSearch.fromQueryObject({ 'span.category': 'ai', 'span.ai.pipeline.group': groupId, }), fields: [ 'ai_total_tokens_used()', 'ai_total_tokens_used(c:spans/ai.total_cost@usd)', ], enabled: Boolean(groupId), }, 'api.ai-pipelines.view' ); const tokenUsedMetric = totalTokenData[0] ?? {}; return ( {t('AI Monitoring')} ); } const SpaceBetweenWrap = styled('div')` display: flex; justify-content: space-between; flex-wrap: wrap; gap: ${space(2)}; `; const MetricsRibbon = styled('div')` display: flex; flex-wrap: wrap; gap: ${space(4)}; `;