Skip to content

Commit e56df2a

Browse files
AlinaVarkkidevtools-frontend-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[AI] Show task-specific widgets insted of CWV widget when a task is selected as context
When the initial context is a call tree, show TIMELINE_RANGE_SUMMARY and BOTTOM_UP_TREE widgets instead of CORE_VITALS widget. This provides more relevant context for analyzing specific tasks. When the context is trace, we still only show CWV widget. Bug: 498329558 Change-Id: If9163f3f608c1552a5185f85267e6224f9407ee5 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7762247 Commit-Queue: Alina Varkki <alinavarkki@chromium.org> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Auto-Submit: Alina Varkki <alinavarkki@chromium.org>
1 parent 4f43615 commit e56df2a

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ Content:
1111
],
1212
"widgets": [
1313
{
14-
"name": "CORE_VITALS"
14+
"name": "TIMELINE_RANGE_SUMMARY"
15+
},
16+
{
17+
"name": "BOTTOM_UP_TREE"
1518
}
1619
]
1720
},

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,33 @@ describeWithMockConnection('PerformanceAgent', function() {
195195
},
196196
]);
197197
});
198+
199+
it('yields TIMELINE_RANGE_SUMMARY and BOTTOM_UP_TREE widgets for call tree focus on initialization',
200+
async function() {
201+
const parsedTrace = await TraceLoader.traceEngine(this, 'web-dev-outermost-frames.json.gz');
202+
const events = allThreadEntriesInTrace(parsedTrace);
203+
const layoutEvt = events.find(event => event.ts === 465457096322);
204+
assert.exists(layoutEvt);
205+
206+
const aiCallTree = AICallTree.AICallTree.fromEvent(layoutEvt, parsedTrace);
207+
assert.exists(aiCallTree);
208+
209+
const agent = new PerformanceAgent.PerformanceAgent({
210+
aidaClient: mockAidaClient([[{explanation: 'done'}]]),
211+
});
212+
213+
const context = PerformanceAgent.PerformanceTraceContext.fromCallTree(aiCallTree);
214+
const responses = await Array.fromAsync(agent.run('test', {selected: context}));
215+
216+
deleteAllWidgetData(responses);
217+
218+
const contextResponse = responses.find(r => r.type === AiAgent.ResponseType.CONTEXT);
219+
assert.exists(contextResponse);
220+
assert.exists(contextResponse.widgets);
221+
assert.lengthOf(contextResponse.widgets, 2);
222+
assert.strictEqual(contextResponse.widgets[0].name, 'TIMELINE_RANGE_SUMMARY');
223+
assert.strictEqual(contextResponse.widgets[1].name, 'BOTTOM_UP_TREE');
224+
});
198225
});
199226

200227
describe('enhanceQuery', () => {

front_end/models/ai_assistance/agents/PerformanceAgent.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
432432
* we only show it once.
433433
*/
434434
#hasShownWidgetForInsightSet = new WeakSet<Trace.Insights.Types.InsightSet>();
435+
#hasShownWidgetForCallTree = new WeakSet<AICallTree>();
435436

436437
get preamble(): string {
437438
return buildPreamble();
@@ -472,16 +473,44 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
472473
contextDisclosure.push(...this.#additionalSelectionsForQuery);
473474

474475
const widgets: AiWidget[] = [];
475-
const primaryInsightSet = context.getItem().primaryInsightSet;
476-
if (primaryInsightSet && !this.#hasShownWidgetForInsightSet.has(primaryInsightSet)) {
477-
widgets.push({
478-
name: 'CORE_VITALS',
479-
data: {
480-
parsedTrace: context.getItem().parsedTrace,
481-
insightSetKey: primaryInsightSet.id,
482-
},
483-
});
484-
this.#hasShownWidgetForInsightSet.add(primaryInsightSet);
476+
const focus = context.getItem();
477+
478+
// If the user has selected a specific task (call tree) as context, show the summary and bottom-up tree for it.
479+
// Otherwise, show the high-level Core Web Vitals widget for the trace or insight.
480+
if (focus.callTree && !this.#hasShownWidgetForCallTree.has(focus.callTree)) {
481+
const event = focus.callTree.selectedNode?.event;
482+
if (event) {
483+
const {startTime, endTime} = Trace.Helpers.Timing.eventTimingsMicroSeconds(event);
484+
const bounds = Trace.Helpers.Timing.traceWindowFromMicroSeconds(startTime, endTime);
485+
widgets.push({
486+
name: 'TIMELINE_RANGE_SUMMARY',
487+
data: {
488+
bounds,
489+
parsedTrace: focus.parsedTrace,
490+
track: 'main',
491+
},
492+
});
493+
widgets.push({
494+
name: 'BOTTOM_UP_TREE',
495+
data: {
496+
bounds,
497+
parsedTrace: focus.parsedTrace,
498+
},
499+
});
500+
this.#hasShownWidgetForCallTree.add(focus.callTree);
501+
}
502+
} else {
503+
const primaryInsightSet = focus.primaryInsightSet;
504+
if (primaryInsightSet && !this.#hasShownWidgetForInsightSet.has(primaryInsightSet)) {
505+
widgets.push({
506+
name: 'CORE_VITALS',
507+
data: {
508+
parsedTrace: focus.parsedTrace,
509+
insightSetKey: primaryInsightSet.id,
510+
},
511+
});
512+
this.#hasShownWidgetForInsightSet.add(primaryInsightSet);
513+
}
485514
}
486515

487516
yield {

0 commit comments

Comments
 (0)