Skip to content

Commit 353a3d8

Browse files
committed
ref(insights): Refactor Insights -> LLM charts
Refactors the Insights -> LLM charts to better support deep linking in a future PR. Notable in this PR is the introduction of a `chartProperties` prop for `LoadableChartWidgetProps`. These are to be used as URL query params when linking to the Releases Drawer, but also used to render the chart as well. They are chart-specific, which is the reason for the additional level of object nesting. Part of #88560
1 parent 17d074d commit 353a3d8

File tree

9 files changed

+149
-127
lines changed

9 files changed

+149
-127
lines changed

static/app/components/events/interfaces/llm-monitoring/llmMonitoringSection.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ import {t} from 'sentry/locale';
55
import type {Event} from 'sentry/types/event';
66
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
77
import * as ModuleLayout from 'sentry/views/insights/common/components/moduleLayout';
8+
import LlmNumberOfPipelinesChartWidget from 'sentry/views/insights/common/components/widgets/llmNumberOfPipelinesChartWidget';
9+
import LlmTotalTokensUsedChart from 'sentry/views/insights/common/components/widgets/llmTotalTokensUsedChartWidget';
810
import {useSpansIndexed} from 'sentry/views/insights/common/queries/useDiscover';
911
import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL';
10-
import {
11-
NumberOfPipelinesChart,
12-
TotalTokensUsedChart,
13-
} from 'sentry/views/insights/llmMonitoring/components/charts/llmMonitoringCharts';
1412
import {SpanIndexedField} from 'sentry/views/insights/types';
1513
import {SectionKey} from 'sentry/views/issueDetails/streamline/context';
1614
import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection';
@@ -53,10 +51,12 @@ export default function LLMMonitoringSection({event}: Props) {
5351
{aiPipelineGroup ? (
5452
<ModuleLayout.Layout>
5553
<ModuleLayout.Half>
56-
<TotalTokensUsedChart groupId={aiPipelineGroup} />
54+
<LlmTotalTokensUsedChart chartProperties={{groupId: aiPipelineGroup}} />
5755
</ModuleLayout.Half>
5856
<ModuleLayout.Half>
59-
<NumberOfPipelinesChart groupId={aiPipelineGroup} />
57+
<LlmNumberOfPipelinesChartWidget
58+
chartProperties={{groupId: aiPipelineGroup}}
59+
/>
6060
</ModuleLayout.Half>
6161
</ModuleLayout.Layout>
6262
) : (

static/app/views/insights/common/components/insightsTimeSeriesWidget.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ import {INGESTION_DELAY} from 'sentry/views/insights/settings';
3636

3737
export interface InsightsTimeSeriesWidgetProps
3838
extends WidgetTitleProps,
39-
LoadableChartWidgetProps {
39+
Omit<LoadableChartWidgetProps, 'chartProperties'>,
40+
Partial<Pick<LoadableChartWidgetProps, 'chartProperties'>> {
4041
error: Error | null;
4142
isLoading: boolean;
4243
series: DiscoverSeries[];
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {useTheme} from '@emotion/react';
2+
3+
import {t} from 'sentry/locale';
4+
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
5+
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
6+
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
7+
import {useSpanMetricsSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
8+
9+
export default function LlmNumberOfPipelinesChartWidget(
10+
props: LoadableChartWidgetProps<{groupId?: string}>
11+
) {
12+
const theme = useTheme();
13+
const aggregate = 'count()';
14+
15+
let query = 'span.category:"ai.pipeline"';
16+
if (props.chartProperties?.groupId) {
17+
query = `${query} span.group:"${props.chartProperties?.groupId}"`;
18+
}
19+
const {data, isPending, error} = useSpanMetricsSeries(
20+
{
21+
yAxis: [aggregate],
22+
search: new MutableSearch(query),
23+
transformAliasToInputFormat: true,
24+
},
25+
'api.ai-pipelines.view'
26+
);
27+
28+
const colors = theme.chart.getColorPalette(2);
29+
return (
30+
<InsightsLineChartWidget
31+
{...props}
32+
id="llmNumberOfPipelinesChartWidget"
33+
title={t('Number of AI pipelines')}
34+
series={[{...data[aggregate], color: colors[1]}]}
35+
isLoading={isPending}
36+
error={error}
37+
/>
38+
);
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {useTheme} from '@emotion/react';
2+
3+
import {t} from 'sentry/locale';
4+
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
5+
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
6+
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
7+
import {useSpanMetricsSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
8+
9+
export default function LlmPipelineDurationChartWidget(
10+
props: LoadableChartWidgetProps<{groupId?: string}>
11+
) {
12+
const theme = useTheme();
13+
const aggregate = 'avg(span.duration)';
14+
15+
let query = 'span.category:"ai.pipeline"';
16+
if (props.chartProperties?.groupId) {
17+
query = `${query} span.group:"${props.chartProperties?.groupId}"`;
18+
}
19+
const {data, isPending, error} = useSpanMetricsSeries(
20+
{
21+
yAxis: [aggregate],
22+
search: new MutableSearch(query),
23+
transformAliasToInputFormat: true,
24+
},
25+
'api.ai-pipelines.view'
26+
);
27+
28+
const colors = theme.chart.getColorPalette(2);
29+
return (
30+
<InsightsLineChartWidget
31+
{...props}
32+
id="llmPipelineDurationChartWidget"
33+
title={t('Pipeline Duration')}
34+
series={[{...data[aggregate], color: colors[2]}]}
35+
isLoading={isPending}
36+
error={error}
37+
/>
38+
);
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {useTheme} from '@emotion/react';
2+
3+
import {t} from 'sentry/locale';
4+
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
5+
import {InsightsLineChartWidget} from 'sentry/views/insights/common/components/insightsLineChartWidget';
6+
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
7+
import {useSpanMetricsSeries} from 'sentry/views/insights/common/queries/useDiscoverSeries';
8+
9+
export default function LlmTotalTokensUsedChartWidget(
10+
props: LoadableChartWidgetProps<{groupId?: string}>
11+
) {
12+
const theme = useTheme();
13+
const aggregate = 'sum(ai.total_tokens.used)';
14+
15+
let query = 'span.category:"ai"';
16+
if (props.chartProperties?.groupId) {
17+
query = `${query} span.ai.pipeline.group:"${props.chartProperties.groupId}"`;
18+
}
19+
const {data, isPending, error} = useSpanMetricsSeries(
20+
{
21+
yAxis: [aggregate],
22+
search: new MutableSearch(query),
23+
transformAliasToInputFormat: true,
24+
},
25+
'api.ai-pipelines.view'
26+
);
27+
28+
const colors = theme.chart.getColorPalette(2);
29+
return (
30+
<InsightsLineChartWidget
31+
{...props}
32+
id="llmTotalTokensUsedChart"
33+
title={t('Total tokens used')}
34+
series={[{...data[aggregate], color: colors[0]}]}
35+
isLoading={isPending}
36+
error={error}
37+
/>
38+
);
39+
}

static/app/views/insights/common/components/widgets/types.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,20 @@ import type {PageFilters} from 'sentry/types/core';
44
* These props are common across components that are required to dynamically
55
* render an Insight Chart Widget
66
*/
7-
export interface LoadableChartWidgetProps {
8-
// TODO(billy): This should be required when all chart widgets are converted
7+
export interface LoadableChartWidgetProps<T = Record<string, string> | undefined> {
8+
/**
9+
* Additional chart-specific properties that are required to render the
10+
* chart. `chartProperties` should be of type Record<string, string> as it
11+
* will be appended to the URL as query parameters so that the chart can be
12+
* linked.
13+
*/
14+
15+
chartProperties?: T;
16+
917
/**
1018
* Unique ID for the widget
19+
*
20+
* TODO(billy): This should be required when all chart widgets are converted
1121
*/
1222
id?: string;
1323

static/app/views/insights/llmMonitoring/components/charts/llmMonitoringCharts.tsx

Lines changed: 0 additions & 102 deletions
This file was deleted.

static/app/views/insights/llmMonitoring/views/llmMonitoringDetailsPage.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul
1616
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
1717
import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper';
1818
import {ReadoutRibbon, ToolRibbon} from 'sentry/views/insights/common/components/ribbon';
19+
import LlmNumberOfPipelinesChartWidget from 'sentry/views/insights/common/components/widgets/llmNumberOfPipelinesChartWidget';
20+
import LlmPipelineDurationChartWidget from 'sentry/views/insights/common/components/widgets/llmPipelineDurationChartWidget';
21+
import LlmTotalTokensUsedChartWidget from 'sentry/views/insights/common/components/widgets/llmTotalTokensUsedChartWidget';
1922
import {useSpanMetrics} from 'sentry/views/insights/common/queries/useDiscover';
20-
import {
21-
NumberOfPipelinesChart,
22-
PipelineDurationChart,
23-
TotalTokensUsedChart,
24-
} from 'sentry/views/insights/llmMonitoring/components/charts/llmMonitoringCharts';
2523
import {PipelineSpansTable} from 'sentry/views/insights/llmMonitoring/components/tables/pipelineSpansTable';
2624
import {RELEASE_LEVEL} from 'sentry/views/insights/llmMonitoring/settings';
2725
import {AiHeader} from 'sentry/views/insights/pages/ai/aiPageHeader';
@@ -148,13 +146,13 @@ function LLMMonitoringPage({params}: Props) {
148146
</HeaderContainer>
149147
</ModuleLayout.Full>
150148
<ModuleLayout.Third>
151-
<TotalTokensUsedChart groupId={groupId} />
149+
<LlmTotalTokensUsedChartWidget chartProperties={{groupId}} />
152150
</ModuleLayout.Third>
153151
<ModuleLayout.Third>
154-
<NumberOfPipelinesChart groupId={groupId} />
152+
<LlmNumberOfPipelinesChartWidget chartProperties={{groupId}} />
155153
</ModuleLayout.Third>
156154
<ModuleLayout.Third>
157-
<PipelineDurationChart groupId={groupId} />
155+
<LlmPipelineDurationChartWidget chartProperties={{groupId}} />
158156
</ModuleLayout.Third>
159157
<ModuleLayout.Full>
160158
<PipelineSpansTable groupId={groupId} />

static/app/views/insights/llmMonitoring/views/llmMonitoringLandingPage.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modul
44
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
55
import {ModulesOnboarding} from 'sentry/views/insights/common/components/modulesOnboarding';
66
import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper';
7-
import {
8-
NumberOfPipelinesChart,
9-
PipelineDurationChart,
10-
TotalTokensUsedChart,
11-
} from 'sentry/views/insights/llmMonitoring/components/charts/llmMonitoringCharts';
7+
import LlmNumberOfPipelinesChartWidget from 'sentry/views/insights/common/components/widgets/llmNumberOfPipelinesChartWidget';
8+
import LlmPipelineDurationChartWidget from 'sentry/views/insights/common/components/widgets/llmPipelineDurationChartWidget';
9+
import LlmTotalTokensUsedChart from 'sentry/views/insights/common/components/widgets/llmTotalTokensUsedChartWidget';
1210
import {PipelinesTable} from 'sentry/views/insights/llmMonitoring/components/tables/pipelinesTable';
1311
import {AiHeader} from 'sentry/views/insights/pages/ai/aiPageHeader';
1412
import {ModuleName} from 'sentry/views/insights/types';
@@ -26,13 +24,13 @@ function LLMMonitoringPage() {
2624
</ModuleLayout.Full>
2725
<ModulesOnboarding moduleName={ModuleName.AI}>
2826
<ModuleLayout.Third>
29-
<TotalTokensUsedChart />
27+
<LlmTotalTokensUsedChart />
3028
</ModuleLayout.Third>
3129
<ModuleLayout.Third>
32-
<NumberOfPipelinesChart />
30+
<LlmNumberOfPipelinesChartWidget />
3331
</ModuleLayout.Third>
3432
<ModuleLayout.Third>
35-
<PipelineDurationChart />
33+
<LlmPipelineDurationChartWidget />
3634
</ModuleLayout.Third>
3735
<ModuleLayout.Full>
3836
<PipelinesTable />

0 commit comments

Comments
 (0)