Skip to content

Commit ce08692

Browse files
jackfranklinDevtools-frontend LUCI CQ
authored andcommitted
RPP: do not pass insight details each time
Bug: 399610873 Change-Id: I4a2135c3726af3e7d356637af223de22389d2c6a Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6387438 Reviewed-by: Ergün Erdoğmuş <[email protected]> Commit-Queue: Jack Franklin <[email protected]> Auto-Submit: Jack Franklin <[email protected]>
1 parent 3353eed commit ce08692

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

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

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,23 @@ import {
2020
} from '../ai_assistance.js';
2121

2222
const FAKE_LCP_MODEL = {
23-
insightKey: 'LCPPhases',
23+
insightKey: Trace.Insights.Types.InsightKeys.LCP_PHASES,
2424
strings: {},
2525
title: 'LCP by phase' as Common.UIString.LocalizedString,
2626
description: 'some description' as Common.UIString.LocalizedString,
2727
category: Trace.Insights.Types.InsightCategory.ALL,
2828
state: 'fail',
2929
frameId: '123',
3030
} as const;
31+
const FAKE_INP_MODEL = {
32+
insightKey: Trace.Insights.Types.InsightKeys.INTERACTION_TO_NEXT_PAINT,
33+
strings: {},
34+
title: 'INP by phase' as Common.UIString.LocalizedString,
35+
description: 'some description' as Common.UIString.LocalizedString,
36+
category: Trace.Insights.Types.InsightCategory.ALL,
37+
state: 'fail',
38+
frameId: '123',
39+
} as const;
3140
const FAKE_PARSED_TRACE = {} as unknown as Trace.Handlers.Types.ParsedTrace;
3241

3342
describeWithEnvironment('PerformanceInsightsAgent', () => {
@@ -144,6 +153,38 @@ What is this?`;
144153

145154
assert.strictEqual(finalQuery, expected);
146155
});
156+
157+
it('does not add the context for follow-up queries with the same context', async () => {
158+
const agent = new PerformanceInsightsAgent({
159+
aidaClient: {} as Host.AidaClient.AidaClient,
160+
});
161+
162+
const mockInsight = new TimelineUtils.InsightAIContext.ActiveInsight(FAKE_LCP_MODEL, FAKE_PARSED_TRACE);
163+
const context = new InsightContext(mockInsight);
164+
165+
await agent.enhanceQuery('What is this?', context);
166+
const finalQuery = await agent.enhanceQuery('Help me understand?', context);
167+
const expected = `# User request:
168+
Help me understand?`;
169+
170+
assert.strictEqual(finalQuery, expected);
171+
});
172+
173+
it('does add context to queries if the insight context changes', async () => {
174+
const agent = new PerformanceInsightsAgent({
175+
aidaClient: {} as Host.AidaClient.AidaClient,
176+
});
177+
const mockInsight1 = new TimelineUtils.InsightAIContext.ActiveInsight(FAKE_LCP_MODEL, FAKE_PARSED_TRACE);
178+
const mockInsight2 = new TimelineUtils.InsightAIContext.ActiveInsight(FAKE_INP_MODEL, FAKE_PARSED_TRACE);
179+
const context1 = new InsightContext(mockInsight1);
180+
const context2 = new InsightContext(mockInsight2);
181+
const firstQuery = await agent.enhanceQuery('Q1', context1);
182+
const secondQuery = await agent.enhanceQuery('Q2', context1);
183+
const thirdQuery = await agent.enhanceQuery('Q3', context2);
184+
assert.include(firstQuery, '## Insight title: LCP by phase');
185+
assert.notInclude(secondQuery, '## Insight title');
186+
assert.include(thirdQuery, '## Insight title: INP by phase');
187+
});
147188
});
148189

149190
describe('function calls', () => {

front_end/models/ai_assistance/agents/PerformanceInsightsAgent.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ You will also be provided with external resources. Use the contents of these res
6969
7070
## Critical requirements
7171
72-
- *CRITICAL* never make the same function call twice.
72+
- *CRITICAL* never call \`getMainThreadActivity\` more than once in a conversation.
73+
- *CRITICAL* never call \`getNetworkActivitySummary\` more than once in a conversation.
7374
- *CRITICAL* make sure you are thorough and call the functions you have access to to give yourself the most information possible to make accurate recommendations.
7475
- *CRITICAL* your text output should NEVER mention the functions that you called. These are an implementation detail and not important for the user to be aware of.
75-
- *CRITICAL* if you are asked about the "Interaction to next paint" insight, make sure you call the \`getMainThreadActivity\` function before making suggestions to the user.
7676
`;
7777
/* clang-format on */
7878

@@ -112,6 +112,8 @@ export class InsightContext extends ConversationContext<TimelineUtils.InsightAIC
112112
export class PerformanceInsightsAgent extends AiAgent<TimelineUtils.InsightAIContext.ActiveInsight> {
113113
#insight: ConversationContext<TimelineUtils.InsightAIContext.ActiveInsight>|undefined;
114114

115+
#lastContextForEnhancedQuery: ConversationContext<TimelineUtils.InsightAIContext.ActiveInsight>|undefined;
116+
115117
override async *
116118
handleContextDetails(activeContext: ConversationContext<TimelineUtils.InsightAIContext.ActiveInsight>|null):
117119
AsyncGenerator<ContextResponse, void, void> {
@@ -223,6 +225,7 @@ export class PerformanceInsightsAgent extends AiAgent<TimelineUtils.InsightAICon
223225

224226
this.declareFunction<Record<never, unknown>, {activity: string}>('getMainThreadActivity', {
225227
description: `Returns the main thread activity for the selected insight.
228+
226229
The tree is represented as a call frame with a root task and a series of children.
227230
The format of each callframe is:
228231
@@ -295,9 +298,17 @@ The fields are:
295298
return query;
296299
}
297300
const formatter = new PerformanceInsightFormatter(selectedInsight.getItem());
298-
const extraQuery = `${formatter.formatInsight()}\n\n# User request:\n`;
301+
302+
// We only need to add Insight info to a prompt when the context changes. For example:
303+
// User clicks Insight A. We need to send info on Insight A with the prompt.
304+
// User asks follow up question. We do not need to resend Insight A with the prompt.
305+
// User clicks Insight B. We now need to send info on Insight B with the prompt.
306+
// User clicks Insight A. We should resend the Insight info with the prompt.
307+
const includeInsightInfo = selectedInsight !== this.#lastContextForEnhancedQuery;
308+
const extraQuery = `${includeInsightInfo ? formatter.formatInsight() + '\n\n' : ''}# User request:\n`;
299309

300310
const finalQuery = `${extraQuery}${query}`;
311+
this.#lastContextForEnhancedQuery = selectedInsight;
301312
return finalQuery;
302313
}
303314

0 commit comments

Comments
 (0)