Skip to content

Commit 25f6b29

Browse files
authored
feat(agents-insights): traffic, duration, issues widgets (#92182)
1 parent 9c7f232 commit 25f6b29

File tree

6 files changed

+161
-3
lines changed

6 files changed

+161
-3
lines changed

static/app/components/charts/chartWidgetLoader.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,14 @@ const CHART_MAP = {
165165
),
166166
overviewRequestsChartWidget: () =>
167167
import('sentry/views/insights/common/components/widgets/overviewRequestsChartWidget'),
168+
overviewAgentsRunsChartWidget: () =>
169+
import(
170+
'sentry/views/insights/common/components/widgets/overviewAgentsRunsChartWidget'
171+
),
172+
overviewAgentsDurationChartWidget: () =>
173+
import(
174+
'sentry/views/insights/common/components/widgets/overviewAgentsDurationChartWidget'
175+
),
168176
} satisfies Record<string, () => Promise<{default: React.FC<LoadableChartWidgetProps>}>>;
169177

170178
/**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// These are the span op we are currently ingesting.
2+
// They will probably change.
3+
const AI_PIPELINE_OPS = ['ai.pipeline.generateText', 'ai.pipeline.generateObject'];
4+
5+
export const getAgentRunsFilter = () => {
6+
return `span.op:[${AI_PIPELINE_OPS.join(',')}]`;
7+
};

static/app/views/insights/agentMonitoring/views/agentsOverviewPage.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLay
2626
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
2727
import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper';
2828
import {ToolRibbon} from 'sentry/views/insights/common/components/ribbon';
29+
import OverviewAgentsDurationChartWidget from 'sentry/views/insights/common/components/widgets/overviewAgentsDurationChartWidget';
30+
import OverviewAgentsRunsChartWidget from 'sentry/views/insights/common/components/widgets/overviewAgentsRunsChartWidget';
2931
import {useOnboardingProject} from 'sentry/views/insights/common/queries/useOnboardingProject';
3032
import {AgentsPageHeader} from 'sentry/views/insights/pages/agents/agentsPageHeader';
33+
import {IssuesWidget} from 'sentry/views/insights/pages/platform/shared/issuesWidget';
3134
import {WidgetGrid} from 'sentry/views/insights/pages/platform/shared/styles';
3235
import {useTransactionNameQuery} from 'sentry/views/insights/pages/platform/shared/useTransactionNameQuery';
3336
import {ModuleName} from 'sentry/views/insights/types';
@@ -76,13 +79,13 @@ function AgentsMonitoringPage() {
7679
<ModuleLayout.Full>
7780
<WidgetGrid>
7881
<WidgetGrid.Position1>
79-
<PlaceholderWidget title="Traffic" />
82+
<OverviewAgentsRunsChartWidget />
8083
</WidgetGrid.Position1>
8184
<WidgetGrid.Position2>
82-
<PlaceholderWidget title="Duration" />
85+
<OverviewAgentsDurationChartWidget />
8386
</WidgetGrid.Position2>
8487
<WidgetGrid.Position3>
85-
<PlaceholderWidget title="Issues" />
88+
<IssuesWidget />
8689
</WidgetGrid.Position3>
8790
<WidgetGrid.Position4>
8891
<PlaceholderWidget title="LLM Generations" />
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {t} from 'sentry/locale';
2+
import {getAgentRunsFilter} from 'sentry/views/insights/agentMonitoring/utils/query';
3+
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
4+
import BaseLatencyWidget from 'sentry/views/insights/pages/platform/shared/baseLatencyWidget';
5+
6+
export default function OverviewAgentsDurationChartWidget(
7+
props: LoadableChartWidgetProps
8+
) {
9+
return (
10+
<BaseLatencyWidget
11+
id="overviewAgentsDurationChartWidget"
12+
title={t('Duration')}
13+
baseQuery={getAgentRunsFilter()}
14+
{...props}
15+
/>
16+
);
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {t} from 'sentry/locale';
2+
import {getAgentRunsFilter} from 'sentry/views/insights/agentMonitoring/utils/query';
3+
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
4+
import {BaseTrafficWidget} from 'sentry/views/insights/pages/platform/shared/baseTrafficWidget';
5+
6+
export default function OverviewAgentsRunsChartWidget(props: LoadableChartWidgetProps) {
7+
return (
8+
<BaseTrafficWidget
9+
id="overviewAgentsRunsChartWidget"
10+
title={t('Traffic')}
11+
trafficSeriesName={t('Runs')}
12+
baseQuery={getAgentRunsFilter()}
13+
{...props}
14+
/>
15+
);
16+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import {useMemo} from 'react';
2+
3+
import {openInsightChartModal} from 'sentry/actionCreators/modal';
4+
import {t} from 'sentry/locale';
5+
import useOrganization from 'sentry/utils/useOrganization';
6+
import {Line} from 'sentry/views/dashboards/widgets/timeSeriesWidget/plottables/line';
7+
import {TimeSeriesWidgetVisualization} from 'sentry/views/dashboards/widgets/timeSeriesWidget/timeSeriesWidgetVisualization';
8+
import {Widget} from 'sentry/views/dashboards/widgets/widget/widget';
9+
import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode';
10+
import {ChartType} from 'sentry/views/insights/common/components/chart';
11+
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
12+
import {useEAPSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
13+
import {convertSeriesToTimeseries} from 'sentry/views/insights/common/utils/convertSeriesToTimeseries';
14+
import {Referrer} from 'sentry/views/insights/pages/platform/laravel/referrers';
15+
import {usePageFilterChartParams} from 'sentry/views/insights/pages/platform/laravel/utils';
16+
import {WidgetVisualizationStates} from 'sentry/views/insights/pages/platform/laravel/widgetVisualizationStates';
17+
import {useReleaseBubbleProps} from 'sentry/views/insights/pages/platform/shared/getReleaseBubbleProps';
18+
import {ModalChartContainer} from 'sentry/views/insights/pages/platform/shared/styles';
19+
import {Toolbar} from 'sentry/views/insights/pages/platform/shared/toolbar';
20+
import {useTransactionNameQuery} from 'sentry/views/insights/pages/platform/shared/useTransactionNameQuery';
21+
22+
interface BaseLatencyWidgetProps extends LoadableChartWidgetProps {
23+
title: string;
24+
baseQuery?: string;
25+
}
26+
27+
export default function BaseLatencyWidget({
28+
title,
29+
baseQuery,
30+
...props
31+
}: BaseLatencyWidgetProps) {
32+
const organization = useOrganization();
33+
const {query} = useTransactionNameQuery();
34+
const pageFilterChartParams = usePageFilterChartParams({
35+
pageFilters: props.pageFilters,
36+
});
37+
const releaseBubbleProps = useReleaseBubbleProps(props);
38+
39+
const fullQuery = `${baseQuery} ${query}`.trim();
40+
41+
const {data, isLoading, error} = useEAPSeries(
42+
{
43+
...pageFilterChartParams,
44+
search: fullQuery,
45+
yAxis: ['avg(span.duration)', 'p95(span.duration)'],
46+
referrer: Referrer.DURATION_CHART,
47+
},
48+
Referrer.DURATION_CHART,
49+
props.pageFilters
50+
);
51+
52+
const plottables = useMemo(() => {
53+
return Object.keys(data).map(key => {
54+
const series = data[key as keyof typeof data];
55+
return new Line(convertSeriesToTimeseries(series));
56+
});
57+
}, [data]);
58+
59+
const isEmpty = plottables.every(plottable => plottable.isEmpty);
60+
61+
const visualization = (
62+
<WidgetVisualizationStates
63+
isLoading={isLoading}
64+
error={error}
65+
isEmpty={isEmpty}
66+
VisualizationType={TimeSeriesWidgetVisualization}
67+
visualizationProps={{
68+
id: props.id,
69+
plottables,
70+
...props,
71+
...releaseBubbleProps,
72+
}}
73+
/>
74+
);
75+
76+
return (
77+
<Widget
78+
Title={<Widget.WidgetTitle title={title} />}
79+
Visualization={visualization}
80+
Actions={
81+
organization.features.includes('visibility-explore-view') &&
82+
!isEmpty && (
83+
<Toolbar
84+
exploreParams={{
85+
mode: Mode.SAMPLES,
86+
visualize: [
87+
{
88+
chartType: ChartType.LINE,
89+
yAxes: ['avg(span.duration)', 'p95(span.duration)'],
90+
},
91+
],
92+
query: fullQuery,
93+
interval: pageFilterChartParams.interval,
94+
}}
95+
loaderSource={props.loaderSource}
96+
onOpenFullScreen={() => {
97+
openInsightChartModal({
98+
title: t('API Latency'),
99+
children: <ModalChartContainer>{visualization}</ModalChartContainer>,
100+
});
101+
}}
102+
/>
103+
)
104+
}
105+
/>
106+
);
107+
}

0 commit comments

Comments
 (0)