Skip to content

Commit 2e34b84

Browse files
AlinaVarkkidevtools-frontend-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[AI] Add support for Image Delivery, font display and slow css selector widgets
https://screenshot.googleplex.com/4cb2ozPTtQypxqj https://screenshot.googleplex.com/9pXchzAoovtkpV8 Bug: 503296282 Change-Id: I09956b4c28870fc6e12562eac48eb1b71a739400 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7806146 Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Commit-Queue: Jack Franklin <jacktfranklin@chromium.org> Auto-Submit: Alina Varkki <alinavarkki@chromium.org>
1 parent 010e26d commit 2e34b84

4 files changed

Lines changed: 138 additions & 0 deletions

File tree

front_end/models/ai_assistance/agents/PerformanceAgent.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,96 @@ code
11571157
assert.strictEqual(widget?.data.insight, Trace.Insights.Types.InsightKeys.DUPLICATE_JAVASCRIPT);
11581158
assert.strictEqual(widget?.data.insightData, insightSet.model.DuplicatedJavaScript);
11591159
});
1160+
1161+
it('yields a PERF_INSIGHT widget for ImageDelivery', async function() {
1162+
insightSet.model.ImageDelivery = {
1163+
insightKey: 'ImageDelivery',
1164+
state: 'fail',
1165+
optimizableImages: [],
1166+
wastedBytes: 0,
1167+
} as unknown as Trace.Insights.Types.InsightModels['ImageDelivery'];
1168+
1169+
const agent = createAgentForConversation({
1170+
aidaClient: mockAidaClient([
1171+
[{
1172+
explanation: '',
1173+
functionCalls: [
1174+
{name: 'getInsightDetails', args: {insightSetId: insightSet.id, insightName: 'ImageDelivery'}},
1175+
]
1176+
}],
1177+
[{explanation: 'done'}]
1178+
])
1179+
});
1180+
1181+
const responses = await Array.fromAsync(agent.run('test', {selected: context}));
1182+
const actions = responses.filter(r => r.type === AiAgent.ResponseType.ACTION);
1183+
assert.lengthOf(actions, 1);
1184+
assert.exists(actions[0].widgets);
1185+
const widget = actions[0].widgets?.find(w => w.name === 'PERF_INSIGHT');
1186+
assert.exists(widget);
1187+
assert.strictEqual(widget?.data.insight, Trace.Insights.Types.InsightKeys.IMAGE_DELIVERY);
1188+
assert.strictEqual(widget?.data.insightData, insightSet.model.ImageDelivery);
1189+
});
1190+
1191+
it('yields a PERF_INSIGHT widget for FontDisplay', async function() {
1192+
insightSet.model.FontDisplay = {
1193+
insightKey: 'FontDisplay',
1194+
state: 'fail',
1195+
fonts: [],
1196+
} as unknown as Trace.Insights.Types.InsightModels['FontDisplay'];
1197+
1198+
const agent = createAgentForConversation({
1199+
aidaClient: mockAidaClient([
1200+
[{
1201+
explanation: '',
1202+
functionCalls: [
1203+
{name: 'getInsightDetails', args: {insightSetId: insightSet.id, insightName: 'FontDisplay'}},
1204+
]
1205+
}],
1206+
[{explanation: 'done'}]
1207+
])
1208+
});
1209+
1210+
const responses = await Array.fromAsync(agent.run('test', {selected: context}));
1211+
const actions = responses.filter(r => r.type === AiAgent.ResponseType.ACTION);
1212+
assert.lengthOf(actions, 1);
1213+
assert.exists(actions[0].widgets);
1214+
const widget = actions[0].widgets?.find(w => w.name === 'PERF_INSIGHT');
1215+
assert.exists(widget);
1216+
assert.strictEqual(widget?.data.insight, Trace.Insights.Types.InsightKeys.FONT_DISPLAY);
1217+
assert.strictEqual(widget?.data.insightData, insightSet.model.FontDisplay);
1218+
});
1219+
1220+
it('yields a PERF_INSIGHT widget for SlowCSSSelector', async function() {
1221+
insightSet.model.SlowCSSSelector = {
1222+
insightKey: 'SlowCSSSelector',
1223+
state: 'fail',
1224+
totalElapsedMs: 0,
1225+
totalMatchAttempts: 0,
1226+
totalMatchCount: 0,
1227+
} as unknown as Trace.Insights.Types.InsightModels['SlowCSSSelector'];
1228+
1229+
const agent = createAgentForConversation({
1230+
aidaClient: mockAidaClient([
1231+
[{
1232+
explanation: '',
1233+
functionCalls: [
1234+
{name: 'getInsightDetails', args: {insightSetId: insightSet.id, insightName: 'SlowCSSSelector'}},
1235+
]
1236+
}],
1237+
[{explanation: 'done'}]
1238+
])
1239+
});
1240+
1241+
const responses = await Array.fromAsync(agent.run('test', {selected: context}));
1242+
const actions = responses.filter(r => r.type === AiAgent.ResponseType.ACTION);
1243+
assert.lengthOf(actions, 1);
1244+
assert.exists(actions[0].widgets);
1245+
const widget = actions[0].widgets?.find(w => w.name === 'PERF_INSIGHT');
1246+
assert.exists(widget);
1247+
assert.strictEqual(widget?.data.insight, Trace.Insights.Types.InsightKeys.SLOW_CSS_SELECTOR);
1248+
assert.strictEqual(widget?.data.insightData, insightSet.model.SlowCSSSelector);
1249+
});
11601250
});
11611251

11621252
it('yields a BOTTOM_UP_TREE widget when getDetailedCallTree is called', async function() {

front_end/models/ai_assistance/agents/PerformanceAgent.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ const SUPPORTED_INSIGHT_WIDGETS = new Set<Trace.Insights.Types.InsightKeys>([
235235
Trace.Insights.Types.InsightKeys.DOCUMENT_LATENCY,
236236
Trace.Insights.Types.InsightKeys.DOM_SIZE,
237237
Trace.Insights.Types.InsightKeys.DUPLICATE_JAVASCRIPT,
238+
Trace.Insights.Types.InsightKeys.IMAGE_DELIVERY,
239+
Trace.Insights.Types.InsightKeys.FONT_DISPLAY,
240+
Trace.Insights.Types.InsightKeys.SLOW_CSS_SELECTOR,
238241
]);
239242

240243
export class PerformanceTraceContext extends ConversationContext<AgentFocus> {

front_end/panels/ai_assistance/components/ChatMessage.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,30 @@ const UIStringsNotTranslate = {
327327
* @description Title for the duplicated JavaScript widget.
328328
*/
329329
duplicateJavaScript: 'Duplicated JavaScript',
330+
/**
331+
* @description Accessible label for the reveal button in the image delivery widget.
332+
*/
333+
revealImageDelivery: 'Reveal image delivery',
334+
/**
335+
* @description Title for the image delivery widget.
336+
*/
337+
imageDelivery: 'Image delivery',
338+
/**
339+
* @description Accessible label for the reveal button in the font display widget.
340+
*/
341+
revealFontDisplay: 'Reveal font display',
342+
/**
343+
* @description Title for the font display widget.
344+
*/
345+
fontDisplay: 'Font display',
346+
/**
347+
* @description Accessible label for the reveal button in the slow CSS selectors widget.
348+
*/
349+
revealSlowCssSelector: 'Reveal slow CSS selectors',
350+
/**
351+
* @description Title for the slow CSS selectors widget.
352+
*/
353+
slowCssSelector: 'Slow CSS selectors',
330354
} as const;
331355

332356
export interface Step {
@@ -1082,6 +1106,24 @@ const INSIGHT_METADATA: Record<string, {
10821106
title: UIStringsNotTranslate.duplicateJavaScript,
10831107
jslog: 'duplicate-javascript-widget',
10841108
},
1109+
[Trace.Insights.Types.InsightKeys.IMAGE_DELIVERY]: {
1110+
component: TimelineInsights.ImageDelivery.ImageDelivery,
1111+
accessibleLabel: UIStringsNotTranslate.revealImageDelivery,
1112+
title: UIStringsNotTranslate.imageDelivery,
1113+
jslog: 'image-delivery-widget',
1114+
},
1115+
[Trace.Insights.Types.InsightKeys.FONT_DISPLAY]: {
1116+
component: TimelineInsights.FontDisplay.FontDisplay,
1117+
accessibleLabel: UIStringsNotTranslate.revealFontDisplay,
1118+
title: UIStringsNotTranslate.fontDisplay,
1119+
jslog: 'font-display-widget',
1120+
},
1121+
[Trace.Insights.Types.InsightKeys.SLOW_CSS_SELECTOR]: {
1122+
component: TimelineInsights.SlowCSSSelector.SlowCSSSelector,
1123+
accessibleLabel: UIStringsNotTranslate.revealSlowCssSelector,
1124+
title: UIStringsNotTranslate.slowCssSelector,
1125+
jslog: 'slow-css-selector-widget',
1126+
},
10851127
};
10861128

10871129
function renderInsightWidget<T extends Trace.Insights.Types.InsightModel>(

front_end/ui/visual_logging/KnownContextValues.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,7 @@ export const knownContextValues = new Set([
17091709
'folder',
17101710
'font',
17111711
'font-display',
1712+
'font-display-widget',
17121713
'font-editor',
17131714
'font-editor-documentation',
17141715
'font-family',
@@ -1978,6 +1979,7 @@ export const knownContextValues = new Set([
19781979
'ignore-this-retainer',
19791980
'image',
19801981
'image-animation',
1982+
'image-delivery-widget',
19811983
'image-orientation',
19821984
'image-rendering',
19831985
'image-url',
@@ -3723,6 +3725,7 @@ export const knownContextValues = new Set([
37233725
'slot',
37243726
'slow',
37253727
'slow-4g',
3728+
'slow-css-selector-widget',
37263729
'sm-script',
37273730
'sm-stylesheet',
37283731
'small',

0 commit comments

Comments
 (0)