Skip to content

Commit 6e4ac0b

Browse files
Connor ClarkDevtools-frontend LUCI CQ
authored andcommitted
[AI] Add getNetworkResourceContent function to full PerformanceAgent
Bypass-Check-License: check is wrong. Bug: 425270067 Change-Id: I0bc2626e389602b331084f4e835862f4689392b6 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6872716 Reviewed-by: Paul Irish <paulirish@chromium.org> Commit-Queue: Connor Clark <cjamcl@chromium.org> Auto-Submit: Connor Clark <cjamcl@chromium.org>
1 parent 465fc4e commit 6e4ac0b

12 files changed

Lines changed: 65 additions & 20 deletions

File tree

config/gni/devtools_grd_files.gni

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,6 @@ grd_files_unbundled_sources = [
19001900
"front_end/panels/timeline/EntriesFilter.js",
19011901
"front_end/panels/timeline/EventsTimelineTreeView.js",
19021902
"front_end/panels/timeline/ExtensionTrackAppender.js",
1903-
"front_end/panels/timeline/FreshRecording.js",
19041903
"front_end/panels/timeline/GPUTrackAppender.js",
19051904
"front_end/panels/timeline/Initiators.js",
19061905
"front_end/panels/timeline/InteractionsTrackAppender.js",
@@ -2038,6 +2037,7 @@ grd_files_unbundled_sources = [
20382037
"front_end/panels/timeline/utils/EntryNodes.js",
20392038
"front_end/panels/timeline/utils/EntryStyles.js",
20402039
"front_end/panels/timeline/utils/EventsSerializer.js",
2040+
"front_end/panels/timeline/utils/FreshRecording.js",
20412041
"front_end/panels/timeline/utils/Helpers.js",
20422042
"front_end/panels/timeline/utils/IgnoreList.js",
20432043
"front_end/panels/timeline/utils/ImageCache.js",

front_end/models/ai_assistance/agents/PerformanceAgent.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as Host from '../../../core/host/host.js';
99
import * as i18n from '../../../core/i18n/i18n.js';
1010
import * as Platform from '../../../core/platform/platform.js';
1111
import * as Root from '../../../core/root/root.js';
12+
import * as SDK from '../../../core/sdk/sdk.js';
1213
import * as TimelineUtils from '../../../panels/timeline/utils/utils.js';
1314
import {html, type TemplateResult} from '../../../ui/lit/lit.js';
1415
import * as Trace from '../../trace/trace.js';
@@ -816,7 +817,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
816817
return;
817818
}
818819

819-
const {parsedTrace, insightSet} = focus.data;
820+
const {parsedTrace, insightSet, traceMetadata} = focus.data;
820821

821822
this.declareFunction<{insightName: string}, {details: string}>('getInsightDetails', {
822823
description:
@@ -1033,6 +1034,51 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
10331034
},
10341035

10351036
});
1037+
1038+
const isFresh = TimelineUtils.FreshRecording.Tracker.instance().recordingIsFresh(parsedTrace);
1039+
const hasScriptContents = traceMetadata.enhancedTraceVersion && parsedTrace.Scripts.scripts.some(s => s.content);
1040+
1041+
if (isFresh || hasScriptContents) {
1042+
this.declareFunction<{url: string}, {content: string}>('getResourceContent', {
1043+
description: 'Returns the content of the resource with the given url. Only use this for text resource types.',
1044+
parameters: {
1045+
type: Host.AidaClient.ParametersTypes.OBJECT,
1046+
description: '',
1047+
nullable: false,
1048+
properties: {
1049+
url: {
1050+
type: Host.AidaClient.ParametersTypes.STRING,
1051+
description: 'The url for the resource.',
1052+
nullable: false,
1053+
},
1054+
},
1055+
},
1056+
displayInfoFromArgs: args => {
1057+
return {title: lockedString('Looking at resource content…'), action: `getResourceContent(${args.url})`};
1058+
},
1059+
handler: async args => {
1060+
debugLog('Function call: getResourceContent');
1061+
1062+
const url = args.url as Platform.DevToolsPath.UrlString;
1063+
const resource = SDK.ResourceTreeModel.ResourceTreeModel.resourceForURL(url);
1064+
if (!resource) {
1065+
if (!resource) {
1066+
return {error: 'Resource not found'};
1067+
}
1068+
}
1069+
1070+
const content = resource.content;
1071+
if (!content) {
1072+
return {error: 'Resource has no content'};
1073+
}
1074+
1075+
const key = `getResourceContent(${args.url})`;
1076+
this.#cacheFunctionResult(focus, key, content);
1077+
return {result: {content}};
1078+
},
1079+
1080+
});
1081+
}
10361082
}
10371083

10381084
#declareFunctions(context: ConversationContext<TimelineUtils.AIContext.AgentFocus>): void {

front_end/panels/timeline/BUILD.gn

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ devtools_module("timeline") {
6767
"EntriesFilter.ts",
6868
"EventsTimelineTreeView.ts",
6969
"ExtensionTrackAppender.ts",
70-
"FreshRecording.ts",
7170
"GPUTrackAppender.ts",
7271
"Initiators.ts",
7372
"InteractionsTrackAppender.ts",
@@ -197,7 +196,6 @@ ts_library("unittests") {
197196
"Breadcrumbs.test.ts",
198197
"CountersGraph.test.ts",
199198
"EntriesFilter.test.ts",
200-
"FreshRecording.test.ts",
201199
"Initiators.test.ts",
202200
"ModificationsManager.test.ts",
203201
"RecordingMetadata.test.ts",

front_end/panels/timeline/TimelineDetailsView.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
1616

1717
import * as TimelineComponents from './components/components.js';
1818
import {EventsTimelineTreeView} from './EventsTimelineTreeView.js';
19-
import {Tracker} from './FreshRecording.js';
2019
import {targetForEvent} from './TargetForEvent.js';
2120
import {ThirdPartyTreeViewWidget} from './ThirdPartyTreeView.js';
2221
import detailsViewStyles from './timelineDetailsView.css.js';
@@ -671,7 +670,8 @@ async function renderSelectedEventDetails(
671670
if (!selectedEvent || !parsedTrace || !linkifier) {
672671
return nothing;
673672
}
674-
const traceRecordingIsFresh = parsedTrace ? Tracker.instance().recordingIsFresh(parsedTrace) : false;
673+
const traceRecordingIsFresh =
674+
parsedTrace ? Utils.FreshRecording.Tracker.instance().recordingIsFresh(parsedTrace) : false;
675675

676676
if (Trace.Types.Events.isSyntheticLayoutShift(selectedEvent) ||
677677
Trace.Types.Events.isSyntheticLayoutShiftCluster(selectedEvent)) {

front_end/panels/timeline/TimelinePanel.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ import * as AnnotationHelpers from './AnnotationHelpers.js';
6464
import {TraceLoadEvent} from './BenchmarkEvents.js';
6565
import * as TimelineComponents from './components/components.js';
6666
import * as TimelineInsights from './components/insights/insights.js';
67-
import {Tracker} from './FreshRecording.js';
6867
import {IsolateSelector} from './IsolateSelector.js';
6968
import {AnnotationModifiedEvent, ModificationsManager} from './ModificationsManager.js';
7069
import * as Overlays from './overlays/overlays.js';
@@ -2564,7 +2563,7 @@ export class TimelinePanel extends Common.ObjectWrapper.eventMixin<EventTypes, t
25642563
}
25652564

25662565
if (recordingIsFresh) {
2567-
Tracker.instance().registerFreshRecording(parsedTrace);
2566+
Utils.FreshRecording.Tracker.instance().registerFreshRecording(parsedTrace);
25682567
}
25692568

25702569
// We store the index of the active trace so we can load it back easily

front_end/panels/timeline/TimelineTreeView.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
1717

1818
import {ActiveFilters} from './ActiveFilters.js';
1919
import * as Extensions from './extensions/extensions.js';
20-
import {Tracker} from './FreshRecording.js';
2120
import {targetForEvent} from './TargetForEvent.js';
2221
import * as ThirdPartyTreeView from './ThirdPartyTreeView.js';
2322
import {TimelineRegExp} from './TimelineFilters.js';
@@ -794,7 +793,8 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
794793
const parsedTrace = this.treeView.parsedTrace();
795794
const target = parsedTrace ? targetForEvent(parsedTrace, event) : null;
796795
const linkifier = this.treeView.linkifier;
797-
const isFreshRecording = Boolean(parsedTrace && Tracker.instance().recordingIsFresh(parsedTrace));
796+
const isFreshRecording =
797+
Boolean(parsedTrace && Utils.FreshRecording.Tracker.instance().recordingIsFresh(parsedTrace));
798798
this.linkElement = TimelineUIUtils.linkifyTopCallFrame(event, target, linkifier, isFreshRecording);
799799
if (this.linkElement) {
800800
container.createChild('div', 'activity-link').appendChild(this.linkElement);

front_end/panels/timeline/TimelineUIUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ import * as UI from '../../ui/legacy/legacy.js';
5454
import {getDurationString} from './AppenderUtils.js';
5555
import * as TimelineComponents from './components/components.js';
5656
import * as Extensions from './extensions/extensions.js';
57-
import {Tracker} from './FreshRecording.js';
5857
import {ModificationsManager} from './ModificationsManager.js';
5958
import {targetForEvent} from './TargetForEvent.js';
6059
import * as ThirdPartyTreeView from './ThirdPartyTreeView.js';
@@ -1021,7 +1020,8 @@ export class TimelineUIUtils {
10211020
}
10221021
}
10231022

1024-
const isFreshRecording = Boolean(parsedTrace && Tracker.instance().recordingIsFresh(parsedTrace));
1023+
const isFreshRecording =
1024+
Boolean(parsedTrace && Utils.FreshRecording.Tracker.instance().recordingIsFresh(parsedTrace));
10251025

10261026
switch (event.name) {
10271027
case Trace.Types.Events.Name.GC:

front_end/panels/timeline/timeline.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import * as CountersGraph from './CountersGraph.js';
1212
import * as EntriesFilter from './EntriesFilter.js';
1313
import * as EventsTimelineTreeView from './EventsTimelineTreeView.js';
1414
import * as ExtensionTrackAppender from './ExtensionTrackAppender.js';
15-
import * as FreshRecording from './FreshRecording.js';
1615
import * as GPUTrackAppender from './GPUTrackAppender.js';
1716
import * as Initiators from './Initiators.js';
1817
import * as InteractionsTrackAppender from './InteractionsTrackAppender.js';
@@ -58,7 +57,6 @@ export {
5857
EntriesFilter,
5958
EventsTimelineTreeView,
6059
ExtensionTrackAppender,
61-
FreshRecording,
6260
GPUTrackAppender,
6361
Initiators,
6462
InteractionsTrackAppender,

front_end/panels/timeline/utils/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ devtools_module("utils") {
1414
"EntryNodes.ts",
1515
"EntryStyles.ts",
1616
"EventsSerializer.ts",
17+
"FreshRecording.ts",
1718
"Helpers.ts",
1819
"IgnoreList.ts",
1920
"ImageCache.ts",
@@ -69,6 +70,7 @@ ts_library("unittests") {
6970
"EntryName.test.ts",
7071
"EntryNodes.test.ts",
7172
"EventsSerializer.test.ts",
73+
"FreshRecording.test.ts",
7274
"Helpers.test.ts",
7375
"IgnoreList.test.ts",
7476
"ImageCache.test.ts",

front_end/panels/timeline/FreshRecording.test.ts renamed to front_end/panels/timeline/utils/FreshRecording.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
6-
import {TraceLoader} from '../../testing/TraceLoader.js';
5+
import {describeWithEnvironment} from '../../../testing/EnvironmentHelpers.js';
6+
import {TraceLoader} from '../../../testing/TraceLoader.js';
77

8-
import * as Timeline from './timeline.js';
8+
import * as Utils from './utils.js';
99

1010
describeWithEnvironment('FreshRecordingTracker', () => {
1111
it('knows that a recording has been registered as fresh', async function() {
12-
const instance = Timeline.FreshRecording.Tracker.instance({forceNew: true});
12+
const instance = Utils.FreshRecording.Tracker.instance({forceNew: true});
1313
const {parsedTrace} = await TraceLoader.traceEngine(this, 'web-dev.json.gz');
1414
instance.registerFreshRecording(parsedTrace);
1515
assert.isTrue(instance.recordingIsFresh(parsedTrace));
1616
});
1717

1818
it('knows that un-registered recordings are not fresh', async function() {
19-
const instance = Timeline.FreshRecording.Tracker.instance({forceNew: true});
19+
const instance = Utils.FreshRecording.Tracker.instance({forceNew: true});
2020
const {parsedTrace} = await TraceLoader.traceEngine(this, 'web-dev.json.gz');
2121
assert.isFalse(instance.recordingIsFresh(parsedTrace));
2222
});

0 commit comments

Comments
 (0)