chrome-devtools-frontend 1.0.1519267 → 1.0.1520535
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/owner/COMMON_OWNERS +1 -2
- package/config/typescript/tsconfig.eslint.json +12 -1
- package/docs/ui_engineering.md +1011 -0
- package/front_end/core/host/GdpClient.ts +26 -5
- package/front_end/core/sdk/NetworkManager.ts +1 -0
- package/front_end/core/sdk/NetworkRequest.ts +10 -0
- package/front_end/entrypoints/main/MainImpl.ts +6 -1
- package/front_end/entrypoints/main/main-meta.ts +3 -3
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +50 -48
- package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +4 -4
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +128 -30
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +98 -63
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +317 -640
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +36 -21
- package/front_end/models/ai_assistance/performance/AICallTree.snapshot.txt +75 -0
- package/front_end/models/ai_assistance/performance/AICallTree.ts +14 -6
- package/front_end/models/ai_assistance/performance/AIContext.ts +62 -7
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +5 -5
- package/front_end/models/badges/Badge.ts +6 -1
- package/front_end/models/badges/StarterBadge.ts +5 -0
- package/front_end/models/badges/UserBadges.ts +5 -4
- package/front_end/models/javascript_metadata/NativeFunctions.js +5 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +14 -7
- package/front_end/panels/ai_assistance/PatchWidget.ts +17 -55
- package/front_end/panels/ai_assistance/components/ChatView.ts +45 -69
- package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +47 -1
- package/front_end/panels/ai_assistance/components/chatView.css +13 -1
- package/front_end/panels/animation/AnimationTimeline.ts +1 -1
- package/front_end/panels/animation/animationTimeline.css +4 -0
- package/front_end/panels/application/preloading/components/PreloadingString.ts +2 -5
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +5 -0
- package/front_end/panels/common/aiCodeCompletionTeaser.css +6 -1
- package/front_end/panels/console/ConsolePrompt.ts +6 -0
- package/front_end/panels/console/ConsoleView.ts +4 -2
- package/front_end/panels/coverage/CoverageListView.ts +146 -198
- package/front_end/panels/coverage/CoverageView.ts +48 -18
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +2 -0
- package/front_end/panels/network/NetworkDataGridNode.ts +22 -0
- package/front_end/panels/network/NetworkLogViewColumns.ts +9 -0
- package/front_end/panels/recorder/components/CreateRecordingView.ts +2 -0
- package/front_end/panels/search/SearchResultsPane.ts +48 -15
- package/front_end/panels/search/SearchView.ts +33 -30
- package/front_end/panels/search/searchView.css +0 -2
- package/front_end/panels/settings/components/SyncSection.ts +4 -4
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +1 -4
- package/front_end/panels/sources/DebuggerPlugin.ts +4 -0
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -1
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +0 -8
- package/front_end/panels/timeline/TimelineFlameChartView.ts +5 -5
- package/front_end/panels/timeline/TimelinePanel.ts +2 -0
- package/front_end/panels/timeline/TimelineTreeView.ts +1 -1
- package/front_end/panels/timeline/components/ExportTraceOptions.ts +56 -4
- package/front_end/panels/timeline/components/exportTraceOptions.css +5 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +8 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/generated/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/PipeTransport.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/PipeTransport.js +15 -16
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/PipeTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Function.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Function.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/generated/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/PipeTransport.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/PipeTransport.js +15 -16
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/PipeTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/Function.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/Function.js.map +1 -1
- package/front_end/third_party/puppeteer/package/package.json +3 -2
- package/front_end/third_party/puppeteer/package/src/generated/version.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/node/PipeTransport.ts +15 -17
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/Function.ts +1 -1
- package/front_end/tsconfig.json +12 -1
- package/front_end/ui/legacy/InspectorView.ts +86 -13
- package/front_end/ui/legacy/TabbedPane.ts +2 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +6 -0
- package/front_end/ui/visual_logging/LoggingEvents.ts +1 -1
- package/package.json +1 -1
@@ -23,7 +23,7 @@ export enum SubscriptionTier {
|
|
23
23
|
PRO_MONTHLY = 'SUBSCRIPTION_TIER_PRO_MONTHLY',
|
24
24
|
}
|
25
25
|
|
26
|
-
enum EligibilityStatus {
|
26
|
+
export enum EligibilityStatus {
|
27
27
|
ELIGIBLE = 'ELIGIBLE',
|
28
28
|
NOT_ELIGIBLE = 'NOT_ELIGIBLE',
|
29
29
|
}
|
@@ -68,6 +68,11 @@ export interface Profile {
|
|
68
68
|
};
|
69
69
|
}
|
70
70
|
|
71
|
+
interface InitializeResult {
|
72
|
+
hasProfile: boolean;
|
73
|
+
isEligible: boolean;
|
74
|
+
}
|
75
|
+
|
71
76
|
// The `batchGet` awards endpoint returns badge names with an
|
72
77
|
// obfuscated user ID (e.g., `profiles/12345/awards/badge-name`).
|
73
78
|
// This function normalizes them to use `me` instead of the ID
|
@@ -114,9 +119,20 @@ export class GdpClient {
|
|
114
119
|
return gdpClientInstance;
|
115
120
|
}
|
116
121
|
|
117
|
-
async initialize(): Promise<
|
118
|
-
|
119
|
-
|
122
|
+
async initialize(): Promise<InitializeResult> {
|
123
|
+
const profile = await this.getProfile();
|
124
|
+
if (profile) {
|
125
|
+
return {
|
126
|
+
hasProfile: true,
|
127
|
+
isEligible: true,
|
128
|
+
};
|
129
|
+
}
|
130
|
+
|
131
|
+
const isEligible = await this.isEligibleToCreateProfile();
|
132
|
+
return {
|
133
|
+
hasProfile: false,
|
134
|
+
isEligible,
|
135
|
+
};
|
120
136
|
}
|
121
137
|
|
122
138
|
async getProfile(): Promise<Profile|null> {
|
@@ -129,7 +145,12 @@ export class GdpClient {
|
|
129
145
|
path: '/v1beta1/profile:get',
|
130
146
|
method: 'GET',
|
131
147
|
});
|
132
|
-
|
148
|
+
|
149
|
+
const profile = await this.#cachedProfilePromise;
|
150
|
+
if (profile) {
|
151
|
+
this.#cachedEligibilityPromise = Promise.resolve({createProfile: EligibilityStatus.ELIGIBLE});
|
152
|
+
}
|
153
|
+
return profile;
|
133
154
|
}
|
134
155
|
|
135
156
|
async checkEligibility(): Promise<CheckElibigilityResponse|null> {
|
@@ -597,6 +597,7 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
|
|
597
597
|
networkRequest.mixedContentType = request.mixedContentType || Protocol.Security.MixedContentType.None;
|
598
598
|
networkRequest.setReferrerPolicy(request.referrerPolicy);
|
599
599
|
networkRequest.setIsSameSite(request.isSameSite || false);
|
600
|
+
networkRequest.setIsAdRelated(request.isAdRelated || false);
|
600
601
|
}
|
601
602
|
|
602
603
|
private updateNetworkRequestWithResponse(networkRequest: NetworkRequest, response: Protocol.Network.Response): void {
|
@@ -320,6 +320,7 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
320
320
|
directSocketInfo?: DirectSocketInfo;
|
321
321
|
readonly #directSocketChunks: DirectSocketChunk[] = [];
|
322
322
|
#isIpProtectionUsed: boolean;
|
323
|
+
#isAdRelated: boolean;
|
323
324
|
|
324
325
|
constructor(
|
325
326
|
requestId: string,
|
@@ -342,6 +343,7 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
342
343
|
this.#initiator = initiator;
|
343
344
|
this.#hasUserGesture = hasUserGesture;
|
344
345
|
this.#isIpProtectionUsed = false;
|
346
|
+
this.#isAdRelated = false;
|
345
347
|
}
|
346
348
|
|
347
349
|
static create(
|
@@ -1850,6 +1852,14 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
1850
1852
|
return this.#isIpProtectionUsed;
|
1851
1853
|
}
|
1852
1854
|
|
1855
|
+
setIsAdRelated(isAdRelated: boolean): void {
|
1856
|
+
this.#isAdRelated = isAdRelated;
|
1857
|
+
}
|
1858
|
+
|
1859
|
+
isAdRelated(): boolean {
|
1860
|
+
return this.#isAdRelated;
|
1861
|
+
}
|
1862
|
+
|
1853
1863
|
getAssociatedData(key: string): object|null {
|
1854
1864
|
return this.#associatedData.get(key) || null;
|
1855
1865
|
}
|
@@ -519,7 +519,12 @@ export class MainImpl {
|
|
519
519
|
|
520
520
|
// Initialize `GDPClient` and `UserBadges` for Google Developer Program integration
|
521
521
|
if (Host.GdpClient.isGdpProfilesAvailable()) {
|
522
|
-
void Host.GdpClient.GdpClient.instance().initialize()
|
522
|
+
void Host.GdpClient.GdpClient.instance().initialize().then(({hasProfile, isEligible}) => {
|
523
|
+
const contextString = hasProfile ? 'has-profile' :
|
524
|
+
isEligible ? 'no-profile-and-eligible' :
|
525
|
+
'no-profile-and-not-eligible';
|
526
|
+
void VisualLogging.logFunctionCall('gdp-client-initialize', contextString);
|
527
|
+
});
|
523
528
|
void Badges.UserBadges.instance().initialize();
|
524
529
|
Badges.UserBadges.instance().addEventListener(Badges.Events.BADGE_TRIGGERED, async ev => {
|
525
530
|
loadedPanelCommonModule ??= await import('../../panels/common/common.js') as typeof PanelCommon;
|
@@ -188,9 +188,9 @@ const UIStrings = {
|
|
188
188
|
browserLanguage: 'Browser UI language',
|
189
189
|
/**
|
190
190
|
* @description Label for a checkbox in the settings UI. Allows developers to opt-in/opt-out
|
191
|
-
* of
|
191
|
+
* of saving settings to their Google account.
|
192
192
|
*/
|
193
|
-
|
193
|
+
saveSettings: 'Save `DevTools` settings to your `Google` account',
|
194
194
|
/**
|
195
195
|
* @description Label for a checkbox in the settings UI. Allows developers to opt-in/opt-out
|
196
196
|
* of receiving Google Developer Program (GDP) badges based on their activity in Chrome DevTools.
|
@@ -789,7 +789,7 @@ Common.Settings.registerSettingExtension({
|
|
789
789
|
// This name must be kept in sync with DevToolsSettings::kSyncDevToolsPreferencesFrontendName.
|
790
790
|
settingName: 'sync-preferences',
|
791
791
|
settingType: Common.Settings.SettingType.BOOLEAN,
|
792
|
-
title: i18nLazyString(UIStrings.
|
792
|
+
title: i18nLazyString(UIStrings.saveSettings),
|
793
793
|
defaultValue: false,
|
794
794
|
reloadRequired: true,
|
795
795
|
});
|
@@ -136,27 +136,13 @@ When referring to a trace event that has a corresponding \`eventKey\`, annotate
|
|
136
136
|
When asking the user to make a choice between multiple options, output a list of choices at the end of your text response. The format is \`SUGGESTIONS: ["suggestion1", "suggestion2", "suggestion3"]\`. This MUST start on a newline, and be a single line.
|
137
137
|
`;
|
138
138
|
|
139
|
-
const
|
139
|
+
const extraPreambleWhenFreshTrace = `Additional notes:
|
140
140
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
* name: A concise string describing the call frame (e.g., 'Evaluate Script', 'render', 'fetchData').
|
147
|
-
* duration: The total execution time of the call frame, including its children.
|
148
|
-
* selfTime: The time spent directly within the call frame, excluding its children's execution.
|
149
|
-
* urlIndex: Index referencing the "All URLs" list. Empty if no specific script URL is associated.
|
150
|
-
* 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.
|
151
|
-
* S: _Optional_. The letter 'S' terminates the line if that call frame was selected by the user.
|
152
|
-
|
153
|
-
Example Call Tree:
|
154
|
-
|
155
|
-
1;main;500;100;;
|
156
|
-
2;update;200;50;;3
|
157
|
-
3;animate;150;20;0;4-5;S
|
158
|
-
4;calculatePosition;80;80;;
|
159
|
-
5;applyStyles;50;50;;
|
141
|
+
When referring to an element for which you know the nodeId, annotate your output using markdown link syntax:
|
142
|
+
- For example, if nodeId is 23: [LCP element](#node-23)
|
143
|
+
- This link will reveal the element in the Elements panel
|
144
|
+
- Never mention node or nodeId when referring to the element, and especially not in the link text.
|
145
|
+
- When referring to the LCP, it's useful to also mention what the LCP element is via its nodeId. Use the markdown link syntax to do so.
|
160
146
|
`;
|
161
147
|
|
162
148
|
enum ScorePriority {
|
@@ -188,7 +174,7 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
|
188
174
|
}
|
189
175
|
|
190
176
|
override getOrigin(): string {
|
191
|
-
const {min, max} = this.#focus.
|
177
|
+
const {min, max} = this.#focus.parsedTrace.data.Meta.traceBounds;
|
192
178
|
return `trace-${min}-${max}`;
|
193
179
|
}
|
194
180
|
|
@@ -197,7 +183,7 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
|
197
183
|
}
|
198
184
|
|
199
185
|
override getTitle(): string {
|
200
|
-
const focus = this.#focus
|
186
|
+
const focus = this.#focus;
|
201
187
|
|
202
188
|
let url = focus.insightSet?.url;
|
203
189
|
if (!url) {
|
@@ -208,6 +194,9 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
|
208
194
|
if (focus.insight) {
|
209
195
|
parts.push(focus.insight.title);
|
210
196
|
}
|
197
|
+
if (focus.event) {
|
198
|
+
parts.push(Trace.Name.forEntry(focus.event));
|
199
|
+
}
|
211
200
|
if (focus.callTree) {
|
212
201
|
const node = focus.callTree.selectedNode ?? focus.callTree.rootNode;
|
213
202
|
parts.push(Trace.Name.forEntry(node.event));
|
@@ -220,9 +209,9 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
|
220
209
|
* "Ask AI".
|
221
210
|
*/
|
222
211
|
override async getSuggestions(): Promise<ConversationSuggestions|undefined> {
|
223
|
-
const
|
212
|
+
const focus = this.#focus;
|
224
213
|
|
225
|
-
if (
|
214
|
+
if (focus.callTree) {
|
226
215
|
return [
|
227
216
|
{title: 'What\'s the purpose of this work?', jslogContext: 'performance-default'},
|
228
217
|
{title: 'Where is time being spent?', jslogContext: 'performance-default'},
|
@@ -230,17 +219,17 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
|
230
219
|
];
|
231
220
|
}
|
232
221
|
|
233
|
-
if (
|
234
|
-
return new PerformanceInsightFormatter(
|
222
|
+
if (focus.insight) {
|
223
|
+
return new PerformanceInsightFormatter(focus, focus.insight).getSuggestions();
|
235
224
|
}
|
236
225
|
|
237
226
|
const suggestions: ConversationSuggestions =
|
238
227
|
[{title: 'What performance issues exist with my page?', jslogContext: 'performance-default'}];
|
239
228
|
|
240
|
-
if (
|
241
|
-
const lcp =
|
242
|
-
const cls =
|
243
|
-
const inp =
|
229
|
+
if (focus.insightSet) {
|
230
|
+
const lcp = focus.insightSet ? Trace.Insights.Common.getLCP(focus.insightSet) : null;
|
231
|
+
const cls = focus.insightSet ? Trace.Insights.Common.getCLS(focus.insightSet) : null;
|
232
|
+
const inp = focus.insightSet ? Trace.Insights.Common.getINP(focus.insightSet) : null;
|
244
233
|
|
245
234
|
const ModelHandlers = Trace.Handlers.ModelHandlers;
|
246
235
|
const GOOD = Trace.Handlers.ModelHandlers.PageLoadMetrics.ScoreClassification.GOOD;
|
@@ -257,9 +246,9 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
|
|
257
246
|
|
258
247
|
// Add up to 3 suggestions from the top failing insights.
|
259
248
|
const top3FailingInsightSuggestions =
|
260
|
-
Object.values(
|
249
|
+
Object.values(focus.insightSet.model)
|
261
250
|
.filter(model => model.state !== 'pass')
|
262
|
-
.map(model => new PerformanceInsightFormatter(
|
251
|
+
.map(model => new PerformanceInsightFormatter(focus, model).getSuggestions().at(-1))
|
263
252
|
.filter(suggestion => !!suggestion)
|
264
253
|
.slice(0, 3);
|
265
254
|
suggestions.push(...top3FailingInsightSuggestions);
|
@@ -278,6 +267,7 @@ const MAX_FUNCTION_RESULT_BYTE_LENGTH = 16384 * 4;
|
|
278
267
|
*/
|
279
268
|
export class PerformanceAgent extends AiAgent<AgentFocus> {
|
280
269
|
#formatter: PerformanceTraceFormatter|null = null;
|
270
|
+
#lastEventForEnhancedQuery: Trace.Types.Events.Event|undefined;
|
281
271
|
#lastInsightForEnhancedQuery: Trace.Insights.Types.InsightModel|undefined;
|
282
272
|
#hasShownAnalyzeTraceContext = false;
|
283
273
|
|
@@ -298,12 +288,16 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
298
288
|
text: extraPreambleWhenNotExternal,
|
299
289
|
metadata: {source: 'devtools', score: ScorePriority.CRITICAL}
|
300
290
|
};
|
291
|
+
#freshTraceExtraPreambleFact: Host.AidaClient.RequestFact = {
|
292
|
+
text: extraPreambleWhenFreshTrace,
|
293
|
+
metadata: {source: 'devtools', score: ScorePriority.CRITICAL}
|
294
|
+
};
|
301
295
|
#networkDataDescriptionFact: Host.AidaClient.RequestFact = {
|
302
296
|
text: PerformanceTraceFormatter.networkDataFormatDescription,
|
303
297
|
metadata: {source: 'devtools', score: ScorePriority.CRITICAL}
|
304
298
|
};
|
305
299
|
#callFrameDataDescriptionFact: Host.AidaClient.RequestFact = {
|
306
|
-
text: callFrameDataFormatDescription,
|
300
|
+
text: PerformanceTraceFormatter.callFrameDataFormatDescription,
|
307
301
|
metadata: {source: 'devtools', score: ScorePriority.CRITICAL}
|
308
302
|
};
|
309
303
|
#traceFacts: Host.AidaClient.RequestFact[] = [];
|
@@ -371,10 +365,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
371
365
|
* 1. go to paulirish.com, record a trace
|
372
366
|
* 2. say "What performance issues exist with my page?"
|
373
367
|
* 3. then say "images"
|
374
|
-
*
|
375
|
-
* TODO(cjamcl): reduce the reliance on this by making sure all URL references
|
376
|
-
* (such as the insight formatters) add the "eventKey" as a suffix, just like all
|
377
|
-
* other events.
|
378
368
|
*/
|
379
369
|
#parseForKnownUrls(response: string): string {
|
380
370
|
const focus = this.context?.getItem();
|
@@ -403,8 +393,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
403
393
|
return match;
|
404
394
|
}
|
405
395
|
|
406
|
-
const request =
|
407
|
-
focus.data.parsedTrace.data.NetworkRequests.byTime.find(request => request.args.data.url === urlText);
|
396
|
+
const request = focus.parsedTrace.data.NetworkRequests.byTime.find(request => request.args.data.url === urlText);
|
408
397
|
if (!request) {
|
409
398
|
return match;
|
410
399
|
}
|
@@ -451,13 +440,21 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
451
440
|
const focus = context.getItem();
|
452
441
|
const selected: string[] = [];
|
453
442
|
|
454
|
-
if (focus.
|
443
|
+
if (focus.event) {
|
444
|
+
const includeEventInfo = focus.event !== this.#lastEventForEnhancedQuery;
|
445
|
+
this.#lastEventForEnhancedQuery = focus.event;
|
446
|
+
if (includeEventInfo) {
|
447
|
+
selected.push(`User selected an event ${this.#formatter?.serializeEvent(focus.event)}.\n\n`);
|
448
|
+
}
|
449
|
+
}
|
450
|
+
|
451
|
+
if (focus.callTree) {
|
455
452
|
// If this is a followup chat about the same call tree, don't include the call tree serialization again.
|
456
453
|
// We don't need to repeat it and we'd rather have more the context window space.
|
457
454
|
let contextString = '';
|
458
|
-
if (!this.#callTreeContextSet.has(focus.
|
459
|
-
contextString = focus.
|
460
|
-
this.#callTreeContextSet.add(focus.
|
455
|
+
if (!this.#callTreeContextSet.has(focus.callTree)) {
|
456
|
+
contextString = focus.callTree.serialize();
|
457
|
+
this.#callTreeContextSet.add(focus.callTree);
|
461
458
|
}
|
462
459
|
|
463
460
|
if (contextString) {
|
@@ -465,17 +462,17 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
465
462
|
}
|
466
463
|
}
|
467
464
|
|
468
|
-
if (focus.
|
465
|
+
if (focus.insight) {
|
469
466
|
// We only need to add Insight info to a prompt when the context changes. For example:
|
470
467
|
// User clicks Insight A. We need to send info on Insight A with the prompt.
|
471
468
|
// User asks follow up question. We do not need to resend Insight A with the prompt.
|
472
469
|
// User clicks Insight B. We now need to send info on Insight B with the prompt.
|
473
470
|
// User clicks Insight A. We should resend the Insight info with the prompt.
|
474
|
-
const includeInsightInfo = focus.
|
475
|
-
this.#lastInsightForEnhancedQuery = focus.
|
471
|
+
const includeInsightInfo = focus.insight !== this.#lastInsightForEnhancedQuery;
|
472
|
+
this.#lastInsightForEnhancedQuery = focus.insight;
|
476
473
|
|
477
474
|
if (includeInsightInfo) {
|
478
|
-
selected.push(`User selected the ${focus.
|
475
|
+
selected.push(`User selected the ${focus.insight.insightKey} insight.\n\n`);
|
479
476
|
}
|
480
477
|
}
|
481
478
|
|
@@ -587,6 +584,11 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
587
584
|
this.addFact(this.#notExternalExtraPreambleFact);
|
588
585
|
}
|
589
586
|
|
587
|
+
const isFresh = Tracing.FreshRecording.Tracker.instance().recordingIsFresh(focus.parsedTrace);
|
588
|
+
if (isFresh) {
|
589
|
+
this.addFact(this.#freshTraceExtraPreambleFact);
|
590
|
+
}
|
591
|
+
|
590
592
|
this.addFact(this.#callFrameDataDescriptionFact);
|
591
593
|
this.addFact(this.#networkDataDescriptionFact);
|
592
594
|
|
@@ -623,7 +625,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
|
|
623
625
|
|
624
626
|
#declareFunctions(context: PerformanceTraceContext): void {
|
625
627
|
const focus = context.getItem();
|
626
|
-
const {parsedTrace, insightSet} = focus
|
628
|
+
const {parsedTrace, insightSet} = focus;
|
627
629
|
|
628
630
|
this.declareFunction<{insightName: string}, {details: string}>('getInsightDetails', {
|
629
631
|
description:
|
@@ -116,11 +116,11 @@ export class PerformanceAnnotationsAgent extends AiAgent<AgentFocus> {
|
|
116
116
|
}
|
117
117
|
|
118
118
|
const focus = context.getItem();
|
119
|
-
if (!focus.
|
119
|
+
if (!focus.callTree) {
|
120
120
|
throw new Error('unexpected context');
|
121
121
|
}
|
122
122
|
|
123
|
-
const callTree = focus.
|
123
|
+
const callTree = focus.callTree;
|
124
124
|
|
125
125
|
yield {
|
126
126
|
type: ResponseType.CONTEXT,
|
@@ -140,11 +140,11 @@ export class PerformanceAnnotationsAgent extends AiAgent<AgentFocus> {
|
|
140
140
|
}
|
141
141
|
|
142
142
|
const focus = context.getItem();
|
143
|
-
if (!focus.
|
143
|
+
if (!focus.callTree) {
|
144
144
|
throw new Error('unexpected context');
|
145
145
|
}
|
146
146
|
|
147
|
-
const callTree = focus.
|
147
|
+
const callTree = focus.callTree;
|
148
148
|
const contextString = callTree.serialize();
|
149
149
|
return `${contextString}\n\n# User request\n\n${query}`;
|
150
150
|
}
|