Skip to content

Commit f55b1d0

Browse files
authored
Performance filters for catalog landing page (#2075)
* Add performance filters to catalog landing page Signed-off-by: manaswinidas <[email protected]> * Fix Cypress tests Signed-off-by: manaswinidas <[email protected]> * Fix Cypress tests Signed-off-by: manaswinidas <[email protected]> * Refactoring and de-duplication Signed-off-by: manaswinidas <[email protected]> * Add Cypress tests and handle models endpoint params when toggle is off Signed-off-by: manaswinidas <[email protected]> --------- Signed-off-by: manaswinidas <[email protected]>
1 parent 3ae136d commit f55b1d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2464
-1347
lines changed

clients/ui/frontend/src/__mocks__/mockCatalogFilterOptionsList.ts

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,48 @@ import {
88
ModelCatalogTask,
99
AllLanguageCode,
1010
UseCaseOptionValue,
11+
DEFAULT_PERFORMANCE_FILTERS_QUERY_NAME,
1112
} from '~/concepts/modelCatalog/const';
1213

1314
export const mockNamedQueries: Record<string, NamedQuery> = {
15+
// Default performance filters applied when performance toggle is turned on
16+
// Uses enum values which now match backend format
17+
[DEFAULT_PERFORMANCE_FILTERS_QUERY_NAME]: {
18+
[ModelCatalogStringFilterKey.USE_CASE]: {
19+
operator: FilterOperator.EQUALS,
20+
value: UseCaseOptionValue.CHATBOT,
21+
},
22+
'artifacts.ttft_p90.double_value': {
23+
operator: FilterOperator.LESS_THAN_OR_EQUAL,
24+
value: 'max', // 'max' means use the max value from the range in filters
25+
},
26+
[ModelCatalogNumberFilterKey.MAX_RPS]: {
27+
operator: FilterOperator.LESS_THAN_OR_EQUAL,
28+
value: 'max', // 'max' means use the max value from the range in filters (300 in mock)
29+
},
30+
},
1431
high_performance_gpu: {
15-
'hardware_type.string_value': { operator: FilterOperator.IN, value: ['H100-80', 'A100-80'] },
16-
'requests_per_second.double_value': {
32+
[ModelCatalogStringFilterKey.HARDWARE_TYPE]: {
33+
operator: FilterOperator.IN,
34+
value: ['H100-80', 'A100-80'],
35+
},
36+
[ModelCatalogNumberFilterKey.MAX_RPS]: {
1737
operator: FilterOperator.GREATER_THAN_OR_EQUAL,
1838
value: 50,
1939
},
2040
},
2141
low_latency: {
22-
'ttft_p90.double_value': { operator: FilterOperator.LESS_THAN, value: 100 },
23-
'e2e_p90.double_value': { operator: FilterOperator.LESS_THAN, value: 500 },
42+
'artifacts.ttft_p90.double_value': { operator: FilterOperator.LESS_THAN, value: 100 },
43+
'artifacts.e2e_p90.double_value': { operator: FilterOperator.LESS_THAN, value: 500 },
2444
},
2545
chatbot_optimized: {
26-
'use_case.string_value': { operator: FilterOperator.EQUALS, value: UseCaseOptionValue.CHATBOT },
46+
[ModelCatalogStringFilterKey.USE_CASE]: {
47+
operator: FilterOperator.EQUALS,
48+
value: UseCaseOptionValue.CHATBOT,
49+
},
2750
},
2851
rag_optimized: {
29-
'use_case.string_value': {
52+
[ModelCatalogStringFilterKey.USE_CASE]: {
3053
operator: FilterOperator.IN,
3154
value: [UseCaseOptionValue.RAG, UseCaseOptionValue.LONG_RAG],
3255
},
@@ -89,75 +112,75 @@ export const mockCatalogFilterOptionsList = (
89112
UseCaseOptionValue.RAG,
90113
],
91114
},
92-
[ModelCatalogNumberFilterKey.MIN_RPS]: {
115+
[ModelCatalogNumberFilterKey.MAX_RPS]: {
93116
type: 'number',
94117
range: {
95118
min: 1,
96119
max: 300,
97120
},
98121
},
99-
// All latency metric combinations for dropdown options
100-
ttft_mean: {
122+
// All latency metric combinations for dropdown options (using full filter key format)
123+
'artifacts.ttft_mean.double_value': {
101124
type: 'number' as const,
102125
range: { min: 20, max: 893 },
103126
},
104-
ttft_p90: {
127+
'artifacts.ttft_p90.double_value': {
105128
type: 'number' as const,
106129
range: { min: 25, max: 600 },
107130
},
108-
ttft_p95: {
131+
'artifacts.ttft_p95.double_value': {
109132
type: 'number' as const,
110133
range: { min: 30, max: 700 },
111134
},
112-
ttft_p99: {
135+
'artifacts.ttft_p99.double_value': {
113136
type: 'number' as const,
114137
range: { min: 40, max: 893 },
115138
},
116-
e2e_mean: {
139+
'artifacts.e2e_mean.double_value': {
117140
type: 'number' as const,
118141
range: { min: 50, max: 800 },
119142
},
120-
e2e_p90: {
143+
'artifacts.e2e_p90.double_value': {
121144
type: 'number' as const,
122145
range: { min: 60, max: 900 },
123146
},
124-
e2e_p95: {
147+
'artifacts.e2e_p95.double_value': {
125148
type: 'number' as const,
126149
range: { min: 70, max: 1000 },
127150
},
128-
e2e_p99: {
151+
'artifacts.e2e_p99.double_value': {
129152
type: 'number' as const,
130153
range: { min: 80, max: 1200 },
131154
},
132-
tps_mean: {
155+
'artifacts.tps_mean.double_value': {
133156
type: 'number' as const,
134157
range: { min: 10, max: 300 },
135158
},
136-
tps_p90: {
159+
'artifacts.tps_p90.double_value': {
137160
type: 'number' as const,
138161
range: { min: 15, max: 350 },
139162
},
140-
tps_p95: {
163+
'artifacts.tps_p95.double_value': {
141164
type: 'number' as const,
142165
range: { min: 20, max: 400 },
143166
},
144-
tps_p99: {
167+
'artifacts.tps_p99.double_value': {
145168
type: 'number' as const,
146169
range: { min: 25, max: 500 },
147170
},
148-
itl_mean: {
171+
'artifacts.itl_mean.double_value': {
149172
type: 'number' as const,
150173
range: { min: 5, max: 100 },
151174
},
152-
itl_p90: {
175+
'artifacts.itl_p90.double_value': {
153176
type: 'number' as const,
154177
range: { min: 8, max: 120 },
155178
},
156-
itl_p95: {
179+
'artifacts.itl_p95.double_value': {
157180
type: 'number' as const,
158181
range: { min: 10, max: 150 },
159182
},
160-
itl_p99: {
183+
'artifacts.itl_p99.double_value': {
161184
type: 'number' as const,
162185
range: { min: 15, max: 200 },
163186
},

clients/ui/frontend/src/__mocks__/mockCatalogModelArtifactList.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ export const mockCatalogPerformanceMetricsArtifact = (
8989
},
9090
use_case: {
9191
metadataType: ModelRegistryMetadataType.STRING,
92-
string_value: UseCaseOptionValue.CODE_FIXING,
92+
// Use CHATBOT as default to match DEFAULT_PERFORMANCE_FILTERS_QUERY_NAME
93+
string_value: UseCaseOptionValue.CHATBOT,
9394
},
9495
},
9596
...partial,
@@ -109,7 +110,7 @@ export const mockCatalogPerformanceMetricsArtifactList = (
109110
partial?: Partial<CatalogPerformanceMetricsArtifact>,
110111
): CatalogPerformanceArtifactList => ({
111112
items: [
112-
// First artifact with base values
113+
// First artifact with base values - uses CHATBOT to match default filters
113114
mockCatalogPerformanceMetricsArtifact({
114115
customProperties: {
115116
config_id: {
@@ -129,7 +130,7 @@ export const mockCatalogPerformanceMetricsArtifactList = (
129130
itl_p90: { metadataType: ModelRegistryMetadataType.DOUBLE, double_value: 7.78 },
130131
use_case: {
131132
metadataType: ModelRegistryMetadataType.STRING,
132-
string_value: UseCaseOptionValue.CODE_FIXING,
133+
string_value: UseCaseOptionValue.CHATBOT,
133134
},
134135
...partial?.customProperties,
135136
},
@@ -158,7 +159,7 @@ export const mockCatalogPerformanceMetricsArtifactList = (
158159
},
159160
},
160161
}),
161-
// Third artifact with different latency values
162+
// Third artifact with CODE_FIXING workload type for testing filter changes
162163
mockCatalogPerformanceMetricsArtifact({
163164
customProperties: {
164165
config_id: {
@@ -178,7 +179,7 @@ export const mockCatalogPerformanceMetricsArtifactList = (
178179
itl_p90: { metadataType: ModelRegistryMetadataType.DOUBLE, double_value: 8.12 },
179180
use_case: {
180181
metadataType: ModelRegistryMetadataType.STRING,
181-
string_value: UseCaseOptionValue.CHATBOT,
182+
string_value: UseCaseOptionValue.CODE_FIXING,
182183
},
183184
},
184185
}),

clients/ui/frontend/src/__tests__/cypress/cypress/pages/modelCatalog.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,17 +240,17 @@ class ModelCatalog {
240240
return cy.findByTestId('validated-model-replicas');
241241
}
242242

243-
findValidatedModelTtft() {
244-
return cy.findByTestId('validated-model-ttft');
243+
findValidatedModelLatency() {
244+
return cy.findByTestId('validated-model-latency');
245245
}
246246

247247
findWorkloadTypeFilter() {
248248
return cy.findByTestId('workload-type-filter');
249249
}
250250

251251
findWorkloadTypeOption(useCaseValue: string) {
252-
// Use the checkbox id attribute (e.g., 'chatbot', 'code_fixing', 'long_rag', 'rag')
253-
return cy.get(`#${useCaseValue}`);
252+
// WorkloadTypeFilter is now single-select dropdown with data-testid
253+
return cy.findByTestId(`workload-type-filter-${useCaseValue}`);
254254
}
255255

256256
selectWorkloadType(useCaseValue: string) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './modelCatalog';
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Shared constants for Model Catalog Cypress tests.
3+
* These test IDs and constants are used across multiple test files.
4+
*/
5+
6+
/**
7+
* Test IDs for performance filter components
8+
*/
9+
export const PERFORMANCE_FILTER_TEST_IDS = {
10+
workloadType: 'workload-type-filter',
11+
latency: 'latency-filter',
12+
latencyContent: 'latency-filter-content',
13+
latencyMetricSelect: 'latency-metric-select',
14+
latencyPercentileSelect: 'latency-percentile-select',
15+
latencyApply: 'latency-apply-filter',
16+
latencyReset: 'latency-reset-filter',
17+
maxRps: 'max-rps-filter',
18+
maxRpsApply: 'max-rps-apply-filter',
19+
hardwareTable: 'hardware-configuration-table',
20+
clearAllFilters: 'clear-all-filters-button',
21+
} as const;
22+
23+
/**
24+
* Test IDs for model catalog card components
25+
*/
26+
export const MODEL_CARD_TEST_IDS = {
27+
card: 'model-catalog-card',
28+
detailLink: 'model-catalog-detail-link',
29+
description: 'model-catalog-card-description',
30+
benchmarkLink: 'validated-model-benchmark-link',
31+
benchmarkNext: 'validated-model-benchmark-next',
32+
benchmarkPrev: 'validated-model-benchmark-prev',
33+
hardware: 'validated-model-hardware',
34+
replicas: 'validated-model-replicas',
35+
latency: 'validated-model-latency',
36+
} as const;
37+
38+
/**
39+
* Test IDs for model catalog details page components
40+
*/
41+
export const MODEL_DETAILS_TEST_IDS = {
42+
tabs: 'model-details-page-tabs',
43+
overviewTab: 'model-overview-tab',
44+
performanceInsightsTab: 'performance-insights-tab',
45+
overviewTabContent: 'model-overview-tab-content',
46+
performanceInsightsTabContent: 'performance-insights-tab-content',
47+
longDescription: 'model-long-description',
48+
} as const;
49+
50+
/**
51+
* Test IDs for alerts
52+
*/
53+
export const ALERT_TEST_IDS = {
54+
performanceFiltersUpdated: 'performance-filters-updated-alert',
55+
} as const;
56+
57+
/**
58+
* Non-breaking space character used in table column headers
59+
*/
60+
export const NBSP = '\u00A0';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Shared intercept helpers for Cypress tests.
3+
* These utilities consolidate common API intercept patterns used across multiple test files.
4+
*/
5+
6+
export * from './modelCatalog';

0 commit comments

Comments
 (0)