Skip to content

Commit 191baa7

Browse files
AlinaVarkkiDevtools-frontend LUCI CQ
authored andcommitted
Move main thread activity format description into a fact
Bug: 410783827 Change-Id: I0d7023e7a5e00f51e891334c5b5256188fa302f8 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6788072 Reviewed-by: Jack Franklin <[email protected]> Auto-Submit: Alina Varkki <[email protected]> Commit-Queue: Alina Varkki <[email protected]>
1 parent f41b551 commit 191baa7

File tree

2 files changed

+58
-18
lines changed

2 files changed

+58
-18
lines changed

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,5 +732,41 @@ Help me understand?`;
732732
`;
733733
assert.deepEqual(networkFormatDescriptionFact.text, expectedFormatDescription);
734734
});
735+
736+
it('sends main thread activity description text as a fact when `getMainThreadActivity` is called',
737+
async function() {
738+
const {parsedTrace, insights} = await TraceLoader.traceEngine(this, 'lcp-discovery-delay.json.gz');
739+
assert.isOk(insights);
740+
const [firstNav] = parsedTrace.Meta.mainFrameNavigations;
741+
const insightSet = getInsightSetOrError(insights, firstNav);
742+
const lcpBreakdown = getInsightOrError('LCPBreakdown', insights, firstNav);
743+
const agent = createAgentForInsightConversation({
744+
aidaClient: mockAidaClient([
745+
[{explanation: '', functionCalls: [{name: 'getMainThreadActivity', args: {}}]}],
746+
]),
747+
});
748+
const context = PerformanceTraceContext.fromInsight(parsedTrace, lcpBreakdown, insightSet.bounds);
749+
await Array.fromAsync(agent.run('test 1', {selected: context}));
750+
assert.strictEqual(agent.currentFacts().size, 1);
751+
const mainThreadActivityDescriptionFact = Array.from(agent.currentFacts()).at(0);
752+
assert.exists(mainThreadActivityDescriptionFact);
753+
754+
const expectedFormatDescription =
755+
`The tree is represented as a call frame with a root task and a series of children.
756+
The format of each callframe is:
757+
758+
'id;name;duration;selfTime;urlIndex;childRange;[S]'
759+
760+
The fields are:
761+
762+
* id: A unique numerical identifier for the call frame.
763+
* name: A concise string describing the call frame (e.g., 'Evaluate Script', 'render', 'fetchData').
764+
* duration: The total execution time of the call frame, including its children.
765+
* selfTime: The time spent directly within the call frame, excluding its children's execution.
766+
* urlIndex: Index referencing the "All URLs" list. Empty if no specific script URL is associated.
767+
* childRange: Specifies the direct children of this node using their IDs. If empty ('' or 'S' at the end), the node has no children. If a single number (e.g., '4'), the node has one child with that ID. If in the format 'firstId-lastId' (e.g., '4-5'), it indicates a consecutive range of child IDs from 'firstId' to 'lastId', inclusive.
768+
* S: **Optional marker.** The letter 'S' appears at the end of the line **only** for the single call frame selected by the user.`;
769+
assert.deepEqual(mainThreadActivityDescriptionFact.text, expectedFormatDescription);
770+
});
735771
});
736772
});

front_end/models/ai_assistance/agents/PerformanceAgent.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,22 @@ const networkDataFormatDescription = `The format is as follows:
196196
The order of headers corresponds to an internal fixed list. If a header is not present, its value will be empty.
197197
`;
198198

199+
const mainThreadActivityFormatDescription =
200+
`The tree is represented as a call frame with a root task and a series of children.
201+
The format of each callframe is:
202+
203+
'id;name;duration;selfTime;urlIndex;childRange;[S]'
204+
205+
The fields are:
206+
207+
* id: A unique numerical identifier for the call frame.
208+
* name: A concise string describing the call frame (e.g., 'Evaluate Script', 'render', 'fetchData').
209+
* duration: The total execution time of the call frame, including its children.
210+
* selfTime: The time spent directly within the call frame, excluding its children's execution.
211+
* urlIndex: Index referencing the "All URLs" list. Empty if no specific script URL is associated.
212+
* childRange: Specifies the direct children of this node using their IDs. If empty ('' or 'S' at the end), the node has no children. If a single number (e.g., '4'), the node has one child with that ID. If in the format 'firstId-lastId' (e.g., '4-5'), it indicates a consecutive range of child IDs from 'firstId' to 'lastId', inclusive.
213+
* S: **Optional marker.** The letter 'S' appears at the end of the line **only** for the single call frame selected by the user.`;
214+
199215
function serializeFocus(focus: TimelineUtils.AIContext.AgentFocus): string {
200216
if (focus.data.type === 'call-tree') {
201217
return focus.data.callTree.serialize();
@@ -408,9 +424,11 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
408424
}>();
409425

410426
/*
411-
* Since don't know for sure if the model will request the network requests information,
412-
* add the format description to facts once the network requests need to be sent.
427+
* Since don't know for sure if the model will request the main thread or network requests information,
428+
* add the formats description to facts once the main thread activity or network requests need to be sent.
413429
*/
430+
#mainThreadActivityDescriptionFact:
431+
Host.AidaClient.RequestFact = {text: mainThreadActivityFormatDescription, metadata: {source: 'devtools'}};
414432
#networkDataDescriptionFact:
415433
Host.AidaClient.RequestFact = {text: networkDataFormatDescription, metadata: {source: 'devtools'}};
416434

@@ -685,22 +703,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
685703
});
686704

687705
this.declareFunction<Record<never, unknown>, {activity: string}>('getMainThreadActivity', {
688-
description: `Returns the main thread activity for the selected insight.
689-
690-
The tree is represented as a call frame with a root task and a series of children.
691-
The format of each callframe is:
692-
693-
'id;name;duration;selfTime;urlIndex;childRange;[S]'
694-
695-
The fields are:
696-
697-
* id: A unique numerical identifier for the call frame.
698-
* name: A concise string describing the call frame (e.g., 'Evaluate Script', 'render', 'fetchData').
699-
* duration: The total execution time of the call frame, including its children.
700-
* selfTime: The time spent directly within the call frame, excluding its children's execution.
701-
* urlIndex: Index referencing the "All URLs" list. Empty if no specific script URL is associated.
702-
* childRange: Specifies the direct children of this node using their IDs. If empty ('' or 'S' at the end), the node has no children. If a single number (e.g., '4'), the node has one child with that ID. If in the format 'firstId-lastId' (e.g., '4-5'), it indicates a consecutive range of child IDs from 'firstId' to 'lastId', inclusive.
703-
* S: **Optional marker.** The letter 'S' appears at the end of the line **only** for the single call frame selected by the user.`,
706+
description: 'Returns the main thread activity for the selected insight.',
704707
parameters: {
705708
type: Host.AidaClient.ParametersTypes.OBJECT,
706709
description: '',
@@ -743,6 +746,7 @@ export class PerformanceAgent extends AiAgent<TimelineUtils.AIContext.AgentFocus
743746
cacheForInsight.getMainThreadActivity = activityFact;
744747
this.#functionCallCache.set(insight, cacheForInsight);
745748

749+
this.addFact(this.#mainThreadActivityDescriptionFact);
746750
return {result: {activity}};
747751
},
748752

0 commit comments

Comments
 (0)