Reland "[AI] Change LcpBreakdownAiWidget into PerfInsightAiWidget to be able to support more insights widgets" This is a reland of commit 8daab95ea9f12bc4445cbedc40e0e2f274f5ca46 Original change's description: > [AI] Change LcpBreakdownAiWidget into PerfInsightAiWidget to be able to support more insights widgets > > Bug: 503296282 > Change-Id: If4183ad5e76614402eeeccc2323138df56e1b917 > Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7768136 > Commit-Queue: Jack Franklin <jacktfranklin@chromium.org> > Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> > Auto-Submit: Alina Varkki <alinavarkki@chromium.org> Bug: 503296282 Change-Id: I73e6cf23ee1cd40fbb9eb994923b0576c4741990 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7772138 Commit-Queue: Alina Varkki <alinavarkki@chromium.org> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
diff --git a/front_end/models/ai_assistance/agents/AiAgent.ts b/front_end/models/ai_assistance/agents/AiAgent.ts index cba90ff..29c3f95 100644 --- a/front_end/models/ai_assistance/agents/AiAgent.ts +++ b/front_end/models/ai_assistance/agents/AiAgent.ts
@@ -248,10 +248,11 @@ }; } -export interface LcpBreakdownAiWidget { - name: 'LCP_BREAKDOWN'; +export interface PerfInsightAiWidget { + name: 'PERF_INSIGHT'; data: { - lcpData: Trace.Insights.Models.LCPBreakdown.LCPBreakdownInsightModel, + insight: 'lcp', + insightData: Trace.Insights.Types.InsightModel, }; } @@ -276,7 +277,7 @@ // This type will grow as we add more widgets. export type AiWidget = ComputedStyleAiWidget|CoreVitalsAiWidget|StylePropertiesAiWidget|DomTreeAiWidget| - PerformanceTraceAiWidget|LcpBreakdownAiWidget|TimelineRangeSummaryAiWidget|BottomUpTreeAiWidget; + PerformanceTraceAiWidget|PerfInsightAiWidget|TimelineRangeSummaryAiWidget|BottomUpTreeAiWidget; export type FunctionCallHandlerResult<Result> = { requiresApproval: true,
diff --git a/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt b/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt index 728f65f..2e4907e 100644 --- a/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +++ b/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt
@@ -43,7 +43,7 @@ ], "widgets": [ { - "name": "LCP_BREAKDOWN" + "name": "PERF_INSIGHT" }, { "name": "CORE_VITALS"
diff --git a/front_end/models/ai_assistance/agents/PerformanceAgent.test.ts b/front_end/models/ai_assistance/agents/PerformanceAgent.test.ts index 45b4961..21d0e21 100644 --- a/front_end/models/ai_assistance/agents/PerformanceAgent.test.ts +++ b/front_end/models/ai_assistance/agents/PerformanceAgent.test.ts
@@ -835,7 +835,7 @@ assert.lengthOf(secondActions[0].widgets!, 1); }); - it('yields an LCP_BREAKDOWN widget when getInsightDetails is called for LCPBreakdown', async function() { + it('yields an lcp-type PERF_INSIGHT widget when getInsightDetails is called for LCPBreakdown', async function() { const parsedTrace = await TraceLoader.traceEngine(this, 'lcp-images.json.gz'); assert.isOk(parsedTrace.insights); const [nav] = parsedTrace.data.Meta.mainFrameNavigations; @@ -873,9 +873,10 @@ assert.lengthOf(actions, 1); assert.exists(actions[0].widgets); - const lcpWidget = actions[0].widgets?.find(w => w.name === 'LCP_BREAKDOWN'); + const lcpWidget = actions[0].widgets?.find(w => w.name === 'PERF_INSIGHT'); assert.exists(lcpWidget); - assert.strictEqual(lcpWidget?.data.lcpData, insightSet.model.LCPBreakdown); + assert.strictEqual(lcpWidget?.data.insight, 'lcp'); + assert.strictEqual(lcpWidget?.data.insightData, insightSet.model.LCPBreakdown); }); it('yields a BOTTOM_UP_TREE widget when getDetailedCallTree is called', async function() {
diff --git a/front_end/models/ai_assistance/agents/PerformanceAgent.ts b/front_end/models/ai_assistance/agents/PerformanceAgent.ts index 275e593..02d9c53 100644 --- a/front_end/models/ai_assistance/agents/PerformanceAgent.ts +++ b/front_end/models/ai_assistance/agents/PerformanceAgent.ts
@@ -527,9 +527,10 @@ if (focus.insight && Trace.Insights.Models.LCPBreakdown.isLCPBreakdownInsight(focus.insight) && !this.#hasShownWidgetForInsight.has(focus.insight)) { widgets.push({ - name: 'LCP_BREAKDOWN', + name: 'PERF_INSIGHT', data: { - lcpData: focus.insight, + insight: 'lcp', + insightData: focus.insight, }, }); this.#hasShownWidgetForInsight.add(focus.insight); @@ -993,9 +994,10 @@ } if (params.insightName === 'LCPBreakdown') { widgets.push({ - name: 'LCP_BREAKDOWN', + name: 'PERF_INSIGHT', data: { - lcpData: insight as Trace.Insights.Models.LCPBreakdown.LCPBreakdownInsightModel, + insight: 'lcp', + insightData: insight as Trace.Insights.Types.InsightModel, }, }); }
diff --git a/front_end/panels/ai_assistance/components/ChatMessage.ts b/front_end/panels/ai_assistance/components/ChatMessage.ts index 266161d..0a662f8 100644 --- a/front_end/panels/ai_assistance/components/ChatMessage.ts +++ b/front_end/panels/ai_assistance/components/ChatMessage.ts
@@ -13,7 +13,7 @@ import * as SDK from '../../../core/sdk/sdk.js'; import type * as Protocol from '../../../generated/protocol.js'; import type { - AiWidget, BottomUpTreeAiWidget, ComputedStyleAiWidget, CoreVitalsAiWidget, DomTreeAiWidget, LcpBreakdownAiWidget, + AiWidget, BottomUpTreeAiWidget, ComputedStyleAiWidget, CoreVitalsAiWidget, DomTreeAiWidget, PerfInsightAiWidget, PerformanceTraceAiWidget, StylePropertiesAiWidget, TimelineRangeSummaryAiWidget} from '../../../models/ai_assistance/agents/AiAgent.js'; import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js'; @@ -879,27 +879,32 @@ }; } -async function makeLcpBreakdownWidget(widgetData: LcpBreakdownAiWidget): Promise<WidgetMakerResponse|null> { - const insight = widgetData.data.lcpData; - if (!insight) { - return null; +async function makePerfInsightWidget(widgetData: PerfInsightAiWidget): Promise<WidgetMakerResponse|null> { + switch (widgetData.data.insight) { + case 'lcp': { + const insight = widgetData.data.insightData; + if (!insight || !Trace.Insights.Models.LCPBreakdown.isLCPBreakdownInsight(insight)) { + return null; + } + // clang-format off + const renderedWidget = html`<devtools-widget + class="lcp-breakdown-widget" + ${widget(TimelineInsights.LCPBreakdown.LCPBreakdown, { + model: insight, + minimal: true, + })}></devtools-widget>`; + // clang-format on + + return { + renderedWidget, + revealable: new TimelineUtils.Helpers.RevealableInsight(insight), + title: lockedString(UIStringsNotTranslate.lcpBreakdown), + jslogContext: 'lcp-breakdown', + }; + } + default: + return null; } - - // clang-format off - const renderedWidget = html`<devtools-widget - class="lcp-breakdown-widget" - ${widget(TimelineInsights.LCPBreakdown.LCPBreakdown, { - model: insight, - minimal: true, - })}></devtools-widget>`; - // clang-format on - - return { - renderedWidget, - revealable: new TimelineUtils.Helpers.RevealableInsight(insight), - title: lockedString(UIStringsNotTranslate.lcpBreakdown), - jslogContext: 'lcp-breakdown', - }; } async function makeBottomUpTimelineTreeWidget(widgetData: BottomUpTreeAiWidget): Promise<WidgetMakerResponse|null> { @@ -1097,8 +1102,8 @@ case 'PERFORMANCE_TRACE': response = await makePerformanceTraceWidget(widgetData); break; - case 'LCP_BREAKDOWN': - response = await makeLcpBreakdownWidget(widgetData); + case 'PERF_INSIGHT': + response = await makePerfInsightWidget(widgetData); break; case 'TIMELINE_RANGE_SUMMARY': response = await makeTimelineRangeSummaryWidget(widgetData);