chrome-devtools-frontend 1.0.1514545 → 1.0.1515796
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/AUTHORS +1 -0
- package/docs/committers_policy.md +1 -1
- package/docs/contributing/infrastructure.md +101 -5
- package/front_end/Images/gdp-logo-dark.png +0 -0
- package/front_end/Images/gdp-logo-light.png +0 -0
- package/front_end/core/common/Settings.ts +11 -32
- package/front_end/entrypoints/main/main-meta.ts +2 -2
- package/front_end/generated/InspectorBackendCommands.js +4 -4
- package/front_end/generated/SupportedCSSProperties.js +12 -0
- package/front_end/generated/protocol.ts +10 -1
- package/front_end/global_typings/global_defs.d.ts +15 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +22 -23
- package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +6 -7
- package/front_end/models/ai_assistance/ai_assistance.ts +3 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +141 -2
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +96 -10
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +123 -55
- package/front_end/models/cpu_profile/ProfileTreeModel.ts +1 -1
- package/front_end/models/extensions/ExtensionPanel.ts +4 -0
- package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +5 -1
- package/front_end/models/javascript_metadata/NativeFunctions.js +7 -7
- package/front_end/models/text_utils/TextUtils.ts +26 -0
- package/front_end/models/trace/Processor.ts +1 -1
- package/front_end/models/trace/helpers/Trace.ts +1 -1
- package/front_end/models/trace/insights/DocumentLatency.ts +9 -7
- package/front_end/models/trace/types/Configuration.ts +12 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +6 -7
- package/front_end/panels/ai_assistance/components/ChatView.ts +1 -2
- package/front_end/panels/application/components/BackForwardCacheStrings.ts +8 -2
- package/front_end/panels/common/BadgeNotification.ts +10 -8
- package/front_end/panels/common/GdpSignUpDialog.ts +25 -16
- package/front_end/panels/common/gdpSignUpDialog.css +10 -14
- package/front_end/panels/console/ConsoleView.ts +4 -0
- package/front_end/panels/elements/ElementsPanel.ts +4 -0
- package/front_end/panels/elements/StylePropertiesSection.ts +4 -4
- package/front_end/panels/network/NetworkConfigView.ts +1 -1
- package/front_end/panels/network/NetworkLogView.ts +2 -2
- package/front_end/panels/network/components/HeaderSectionRow.ts +2 -3
- package/front_end/panels/profiler/HeapProfileView.ts +1 -3
- package/front_end/panels/profiler/HeapSnapshotView.ts +5 -1
- package/front_end/panels/profiler/ProfileDataGrid.ts +4 -0
- package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +7 -29
- package/front_end/panels/profiler/ProfileView.ts +4 -0
- package/front_end/panels/recorder/components/CreateRecordingView.ts +2 -2
- package/front_end/panels/search/SearchView.ts +322 -248
- package/front_end/panels/settings/KeybindsSettingsTab.ts +1 -1
- package/front_end/panels/settings/SettingsScreen.ts +1 -1
- package/front_end/panels/settings/components/SyncSection.ts +59 -14
- package/front_end/panels/settings/components/syncSection.css +17 -4
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +4 -7
- package/front_end/panels/sources/SourcesView.ts +4 -0
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +2 -2
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +6 -3
- package/front_end/panels/timeline/CountersGraph.ts +5 -5
- package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +4 -3
- package/front_end/panels/timeline/TimelineFlameChartView.ts +9 -4
- package/front_end/panels/timeline/TimelineHistoryManager.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +4 -3
- package/front_end/panels/timeline/TimelineTreeView.ts +6 -2
- package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +2 -2
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +6 -6
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +2 -2
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -3
- package/front_end/panels/timeline/utils/utils.ts +0 -8
- package/front_end/panels/webauthn/WebauthnPane.ts +1 -1
- package/front_end/{panels/timeline/utils → services/tracing}/FreshRecording.ts +1 -1
- package/front_end/services/tracing/tracing.ts +2 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/README.md +6 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +11 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +30 -8
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +1 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- 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/cdp/NetworkManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- 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.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js +5 -0
- 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/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +12 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +22 -8
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +11 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +30 -8
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +1 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- 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.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js +5 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +12 -2
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +13 -2
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +50 -8
- package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +0 -1
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +8 -1
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +21 -5
- package/front_end/third_party/puppeteer/package/src/generated/version.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +12 -0
- package/front_end/ui/components/text_editor/config.ts +66 -16
- package/front_end/ui/legacy/Dialog.ts +38 -13
- package/front_end/ui/legacy/InspectorView.ts +7 -9
- package/front_end/ui/legacy/ProgressIndicator.ts +4 -5
- package/front_end/ui/legacy/SearchableView.ts +73 -55
- package/front_end/ui/legacy/SettingsUI.ts +5 -5
- package/front_end/ui/legacy/components/color_picker/Spectrum.ts +1 -4
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +5 -5
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +4 -2
- package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +1 -4
- package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +3 -3
- package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/JSONView.ts +10 -10
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -0
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +4 -0
- package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -4
- package/front_end/ui/legacy/searchableView.css +0 -4
- package/front_end/ui/visual_logging/Debugging.ts +24 -12
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +3 -3
- package/front_end/Images/src/gdp-logo-standalone.svg +0 -9
- /package/front_end/{panels/timeline/utils → models/ai_assistance/performance}/AICallTree.ts +0 -0
- /package/front_end/{panels/timeline/utils → models/ai_assistance/performance}/AIContext.ts +0 -0
- /package/front_end/{panels/timeline/utils/InsightAIContext.ts → models/ai_assistance/performance/AIQueries.ts} +0 -0
@@ -202,70 +202,133 @@ export class AiCodeCompletion extends Common.ObjectWrapper.ObjectWrapper<EventTy
|
|
202
202
|
};
|
203
203
|
}
|
204
204
|
|
205
|
+
async #completeCodeCached(request: Host.AidaClient.CompletionRequest): Promise<{
|
206
|
+
response: Host.AidaClient.CompletionResponse | null,
|
207
|
+
fromCache: boolean,
|
208
|
+
}> {
|
209
|
+
const cachedResponse = this.#checkCachedRequestForResponse(request);
|
210
|
+
if (cachedResponse) {
|
211
|
+
return {response: cachedResponse, fromCache: true};
|
212
|
+
}
|
213
|
+
|
214
|
+
const response = await this.#aidaClient.completeCode(request);
|
215
|
+
if (!response) {
|
216
|
+
return {
|
217
|
+
response: null,
|
218
|
+
fromCache: false,
|
219
|
+
};
|
220
|
+
}
|
221
|
+
|
222
|
+
this.#updateCachedRequest(request, response);
|
223
|
+
return {
|
224
|
+
response,
|
225
|
+
fromCache: false,
|
226
|
+
};
|
227
|
+
}
|
228
|
+
|
229
|
+
#pickSampleFromResponse(response: Host.AidaClient.CompletionResponse): Host.AidaClient.GenerationSample|null {
|
230
|
+
if (!response.generatedSamples.length) {
|
231
|
+
return null;
|
232
|
+
}
|
233
|
+
|
234
|
+
// `currentHint` is the portion of a standard autocomplete suggestion that the user has not yet typed.
|
235
|
+
// For example, if the user types `document.queryS` and the autocomplete suggests `document.querySelector`,
|
236
|
+
// the `currentHint` is `elector`.
|
237
|
+
const currentHintInMenu = this.#editor.editor.plugin(TextEditor.Config.showCompletionHint)?.currentHint;
|
238
|
+
// TODO(ergunsh): We should not do this check here. Instead, the AI code suggestions should be provided
|
239
|
+
// as it is to the view plugin. The view plugin should choose which one to use based on the completion hint
|
240
|
+
// and selected completion.
|
241
|
+
if (!currentHintInMenu) {
|
242
|
+
return response.generatedSamples[0];
|
243
|
+
}
|
244
|
+
|
245
|
+
// TODO(ergunsh): This does not handle looking for `selectedCompletion`. The `currentHint` is `null`
|
246
|
+
// for the Sources panel case.
|
247
|
+
// Even though there is no match, we still return the first suggestion which will be displayed
|
248
|
+
// when the traditional autocomplete menu is closed.
|
249
|
+
return response.generatedSamples.find(sample => sample.generationString.startsWith(currentHintInMenu)) ??
|
250
|
+
response.generatedSamples[0];
|
251
|
+
}
|
252
|
+
|
253
|
+
async #generateSampleForRequest(request: Host.AidaClient.CompletionRequest, cursor: number): Promise<{
|
254
|
+
suggestionText: string,
|
255
|
+
sampleId: number,
|
256
|
+
fromCache: boolean,
|
257
|
+
citations: Host.AidaClient.Citation[],
|
258
|
+
rpcGlobalId?: Host.AidaClient.RpcGlobalId,
|
259
|
+
}|null> {
|
260
|
+
const {response, fromCache} = await this.#completeCodeCached(request);
|
261
|
+
debugLog('At cursor position', cursor, {request, response, fromCache});
|
262
|
+
if (!response) {
|
263
|
+
return null;
|
264
|
+
}
|
265
|
+
|
266
|
+
const suggestionSample = this.#pickSampleFromResponse(response);
|
267
|
+
if (!suggestionSample) {
|
268
|
+
return null;
|
269
|
+
}
|
270
|
+
|
271
|
+
const shouldBlock =
|
272
|
+
suggestionSample.attributionMetadata?.attributionAction === Host.AidaClient.RecitationAction.BLOCK;
|
273
|
+
if (shouldBlock) {
|
274
|
+
return null;
|
275
|
+
}
|
276
|
+
|
277
|
+
const suggestionText = this.#trimSuggestionOverlap(suggestionSample.generationString, request);
|
278
|
+
if (suggestionText.length === 0) {
|
279
|
+
return null;
|
280
|
+
}
|
281
|
+
|
282
|
+
return {
|
283
|
+
suggestionText,
|
284
|
+
sampleId: suggestionSample.sampleId,
|
285
|
+
fromCache,
|
286
|
+
citations: suggestionSample.attributionMetadata?.citations ?? [],
|
287
|
+
rpcGlobalId: response.metadata.rpcGlobalId,
|
288
|
+
};
|
289
|
+
}
|
290
|
+
|
205
291
|
async #requestAidaSuggestion(request: Host.AidaClient.CompletionRequest, cursor: number): Promise<void> {
|
206
292
|
const startTime = performance.now();
|
207
|
-
let servedFromCache = false;
|
208
293
|
this.dispatchEventToListeners(Events.REQUEST_TRIGGERED, {});
|
209
294
|
|
210
295
|
try {
|
211
|
-
|
212
|
-
if (!
|
213
|
-
|
214
|
-
|
215
|
-
this.#updateCachedRequest(request, response);
|
216
|
-
}
|
217
|
-
} else {
|
218
|
-
servedFromCache = true;
|
296
|
+
const sampleResponse = await this.#generateSampleForRequest(request, cursor);
|
297
|
+
if (!sampleResponse) {
|
298
|
+
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {});
|
299
|
+
return;
|
219
300
|
}
|
220
|
-
debugLog('At cursor position', cursor, {request, response});
|
221
|
-
if (response && response.generatedSamples.length > 0 && response.generatedSamples[0].generationString) {
|
222
|
-
if (response.generatedSamples[0].attributionMetadata?.attributionAction ===
|
223
|
-
Host.AidaClient.RecitationAction.BLOCK) {
|
224
|
-
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {});
|
225
|
-
return;
|
226
|
-
}
|
227
301
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
302
|
+
const {
|
303
|
+
suggestionText,
|
304
|
+
sampleId,
|
305
|
+
fromCache,
|
306
|
+
citations,
|
307
|
+
rpcGlobalId,
|
308
|
+
} = sampleResponse;
|
309
|
+
const remainingDelay = Math.max(DELAY_BEFORE_SHOWING_RESPONSE_MS - (performance.now() - startTime), 0);
|
310
|
+
this.#renderingTimeout = window.setTimeout(() => {
|
311
|
+
this.#editor.dispatch({
|
312
|
+
effects: TextEditor.Config.setAiAutoCompleteSuggestion.of({
|
313
|
+
text: suggestionText,
|
314
|
+
from: cursor,
|
315
|
+
rpcGlobalId,
|
316
|
+
sampleId,
|
317
|
+
})
|
318
|
+
});
|
319
|
+
|
320
|
+
if (fromCache) {
|
321
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiCodeCompletionResponseServedFromCache);
|
232
322
|
}
|
233
|
-
|
234
|
-
|
235
|
-
|
323
|
+
|
324
|
+
if (rpcGlobalId) {
|
325
|
+
const latency = performance.now() - startTime;
|
326
|
+
this.#registerUserImpression(rpcGlobalId, sampleId, latency);
|
236
327
|
}
|
237
328
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
// We are not cancelling the previous responses even when there are more recent responses
|
242
|
-
// from the LLM as:
|
243
|
-
// In case the user kept typing characters that are prefix of the previous suggestion, it
|
244
|
-
// is a valid suggestion and we should display it to the user.
|
245
|
-
// In case the user typed a different character, the config for AI auto complete suggestion
|
246
|
-
// will set the suggestion to null.
|
247
|
-
this.#editor.dispatch({
|
248
|
-
effects: TextEditor.Config.setAiAutoCompleteSuggestion.of({
|
249
|
-
text: suggestionText,
|
250
|
-
from: cursor,
|
251
|
-
rpcGlobalId: response.metadata.rpcGlobalId,
|
252
|
-
sampleId: response.generatedSamples[0].sampleId,
|
253
|
-
})
|
254
|
-
});
|
255
|
-
if (servedFromCache) {
|
256
|
-
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiCodeCompletionResponseServedFromCache);
|
257
|
-
}
|
258
|
-
debugLog('Suggestion dispatched to the editor', response.generatedSamples[0], 'at cursor position', cursor);
|
259
|
-
if (response.metadata.rpcGlobalId) {
|
260
|
-
const latency = performance.now() - startTime;
|
261
|
-
this.#registerUserImpression(response.metadata.rpcGlobalId, response.generatedSamples[0].sampleId, latency);
|
262
|
-
}
|
263
|
-
const citations = response.generatedSamples[0].attributionMetadata?.citations;
|
264
|
-
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {citations});
|
265
|
-
}, remainderDelay);
|
266
|
-
} else {
|
267
|
-
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {});
|
268
|
-
}
|
329
|
+
debugLog('Suggestion dispatched to the editor', suggestionText, 'at cursor position', cursor);
|
330
|
+
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {citations});
|
331
|
+
}, remainingDelay);
|
269
332
|
} catch (e) {
|
270
333
|
debugLog('Error while fetching code completion suggestions from AIDA', e);
|
271
334
|
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {});
|
@@ -289,7 +352,12 @@ export class AiCodeCompletion extends Common.ObjectWrapper.ObjectWrapper<EventTy
|
|
289
352
|
/**
|
290
353
|
* Removes the end of a suggestion if it overlaps with the start of the suffix.
|
291
354
|
*/
|
292
|
-
#trimSuggestionOverlap(generationString: string,
|
355
|
+
#trimSuggestionOverlap(generationString: string, request: Host.AidaClient.CompletionRequest): string {
|
356
|
+
const suffix = request.suffix;
|
357
|
+
if (!suffix) {
|
358
|
+
return generationString;
|
359
|
+
}
|
360
|
+
|
293
361
|
// Iterate from the longest possible overlap down to the shortest
|
294
362
|
for (let i = Math.min(generationString.length, suffix.length); i > 0; i--) {
|
295
363
|
const overlapCandidate = suffix.substring(0, i);
|
@@ -239,12 +239,16 @@ export class NodeFilter {
|
|
239
239
|
export class SearchConfig {
|
240
240
|
query: string;
|
241
241
|
caseSensitive: boolean;
|
242
|
+
wholeWord: boolean;
|
242
243
|
isRegex: boolean;
|
243
244
|
shouldJump: boolean;
|
244
245
|
jumpBackward: boolean;
|
245
|
-
constructor(
|
246
|
+
constructor(
|
247
|
+
query: string, caseSensitive: boolean, wholeWord: boolean, isRegex: boolean, shouldJump: boolean,
|
248
|
+
jumpBackward: boolean) {
|
246
249
|
this.query = query;
|
247
250
|
this.caseSensitive = caseSensitive;
|
251
|
+
this.wholeWord = wholeWord;
|
248
252
|
this.isRegex = isRegex;
|
249
253
|
this.shouldJump = shouldJump;
|
250
254
|
this.jumpBackward = jumpBackward;
|
@@ -6088,7 +6088,7 @@ export const NativeFunctions = [
|
|
6088
6088
|
},
|
6089
6089
|
{
|
6090
6090
|
name: "addAnimation",
|
6091
|
-
signatures: [["animation"]]
|
6091
|
+
signatures: [["animation","action","behavior"]]
|
6092
6092
|
},
|
6093
6093
|
{
|
6094
6094
|
name: "removeAnimation",
|
@@ -6765,6 +6765,10 @@ export const NativeFunctions = [
|
|
6765
6765
|
name: "DragEvent",
|
6766
6766
|
signatures: [["type","?eventInitDict"]]
|
6767
6767
|
},
|
6768
|
+
{
|
6769
|
+
name: "EmailVerifiedEvent",
|
6770
|
+
signatures: [["type","?eventInitDict"]]
|
6771
|
+
},
|
6768
6772
|
{
|
6769
6773
|
name: "ErrorEvent",
|
6770
6774
|
signatures: [["type","?eventInitDict"]]
|
@@ -7605,7 +7609,7 @@ export const NativeFunctions = [
|
|
7605
7609
|
signatures: [["element","x","y","?dwidth","?dheight"]]
|
7606
7610
|
},
|
7607
7611
|
{
|
7608
|
-
name: "
|
7612
|
+
name: "drawElementImage",
|
7609
7613
|
signatures: [["element","x","y","?dwidth","?dheight"]]
|
7610
7614
|
},
|
7611
7615
|
{
|
@@ -8420,10 +8424,6 @@ export const NativeFunctions = [
|
|
8420
8424
|
name: "RTCRtpScriptTransform",
|
8421
8425
|
signatures: [["worker","?options","?transfer"]]
|
8422
8426
|
},
|
8423
|
-
{
|
8424
|
-
name: "sendRtp",
|
8425
|
-
signatures: [["packet","options"]]
|
8426
|
-
},
|
8427
8427
|
{
|
8428
8428
|
name: "setHeaderExtensionsToNegotiate",
|
8429
8429
|
signatures: [["extensions"]]
|
@@ -8891,7 +8891,7 @@ export const NativeFunctions = [
|
|
8891
8891
|
signatures: [["provokeMode"]]
|
8892
8892
|
},
|
8893
8893
|
{
|
8894
|
-
name: "
|
8894
|
+
name: "texElementImage2D",
|
8895
8895
|
signatures: [["target","level","internalformat","format","type","element"]]
|
8896
8896
|
},
|
8897
8897
|
{
|
@@ -367,6 +367,32 @@ export const performSearchInSearchMatches = function(
|
|
367
367
|
return result;
|
368
368
|
};
|
369
369
|
|
370
|
+
/**
|
371
|
+
* Finds the longest overlapping string segment between the end of the first
|
372
|
+
* string and the beginning of the second string.
|
373
|
+
*
|
374
|
+
* @param s1 The first string (whose suffix will be checked).
|
375
|
+
* @param s2 The second string (whose prefix will be checked).
|
376
|
+
* @returns The overlapping string segment, or an empty string ("")
|
377
|
+
* if no overlap is found.
|
378
|
+
*/
|
379
|
+
export const getOverlap = function(s1: string, s2: string): string|null {
|
380
|
+
const minLen = Math.min(s1.length, s2.length);
|
381
|
+
// Check from longest possible overlap down to 1
|
382
|
+
for (let n = minLen; n > 0; n--) {
|
383
|
+
// slice(-n) gets the last 'n' chars
|
384
|
+
const suffix = s1.slice(-n);
|
385
|
+
// substring(0, n) gets the first 'n' chars
|
386
|
+
const prefix = s2.substring(0, n);
|
387
|
+
|
388
|
+
if (suffix === prefix) {
|
389
|
+
return suffix;
|
390
|
+
}
|
391
|
+
}
|
392
|
+
|
393
|
+
return null;
|
394
|
+
};
|
395
|
+
|
370
396
|
export interface ParsedFilter {
|
371
397
|
key?: string;
|
372
398
|
text?: string|null;
|
@@ -443,7 +443,7 @@ export class TraceProcessor extends EventTarget {
|
|
443
443
|
let model: Insights.Types.InsightModel|Error;
|
444
444
|
try {
|
445
445
|
options.logger?.start(`insights:${name}`);
|
446
|
-
model = insight.generateInsight(data, context);
|
446
|
+
model = insight.generateInsight(data, context, options.insightTimeFormatters);
|
447
447
|
model.frameId = context.frameId;
|
448
448
|
const navId = context.navigation?.args.data?.navigationId;
|
449
449
|
if (navId) {
|
@@ -766,7 +766,7 @@ export function extractSampleTraceId(event: Types.Events.Event): number|null {
|
|
766
766
|
return event.args?.sampleTraceId ?? event.args?.data?.sampleTraceId ?? null;
|
767
767
|
}
|
768
768
|
|
769
|
-
// This exactly matches
|
769
|
+
// This exactly matches Trace.Styles.visibleTypes. See the runtime verification in maybeInitStylesMap.
|
770
770
|
// TODO(crbug.com/410884528)
|
771
771
|
export const VISIBLE_TRACE_EVENT_TYPES = new Set<Types.Events.Name>([
|
772
772
|
Types.Events.Name.ABORT_POST_TASK_CALLBACK,
|
@@ -190,11 +190,14 @@ function finalize(partialModel: PartialInsightModel<DocumentLatencyInsightModel>
|
|
190
190
|
}
|
191
191
|
|
192
192
|
export function generateInsight(
|
193
|
-
data: Handlers.Types.HandlerData, context: InsightSetContext
|
193
|
+
data: Handlers.Types.HandlerData, context: InsightSetContext,
|
194
|
+
timeFormatters?: Types.Configuration.InsightTimeFormatters): DocumentLatencyInsightModel {
|
194
195
|
if (!context.navigation) {
|
195
196
|
return finalize({});
|
196
197
|
}
|
197
198
|
|
199
|
+
const millisToString = timeFormatters?.milli ?? i18n.TimeUtilities.millisToString;
|
200
|
+
|
198
201
|
const documentRequest = data.NetworkRequests.byId.get(context.navigationId);
|
199
202
|
if (!documentRequest) {
|
200
203
|
return finalize({warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
|
@@ -212,7 +215,8 @@ export function generateInsight(
|
|
212
215
|
overallSavingsMs = Math.max(serverResponseTime - TARGET_MS, 0);
|
213
216
|
}
|
214
217
|
|
215
|
-
const redirectDuration =
|
218
|
+
const redirectDuration =
|
219
|
+
Math.round(documentRequest.args.data.syntheticData.redirectionDuration / 1000) as Types.Timing.Milli;
|
216
220
|
overallSavingsMs += redirectDuration;
|
217
221
|
|
218
222
|
const metricSavings = {
|
@@ -237,16 +241,14 @@ export function generateInsight(
|
|
237
241
|
noRedirects: {
|
238
242
|
label: noRedirects ? i18nString(UIStrings.passingRedirects) : i18nString(UIStrings.failedRedirects, {
|
239
243
|
PH1: documentRequest.args.data.redirects.length,
|
240
|
-
PH2:
|
244
|
+
PH2: millisToString(redirectDuration),
|
241
245
|
}),
|
242
246
|
value: noRedirects
|
243
247
|
},
|
244
248
|
serverResponseIsFast: {
|
245
249
|
label: serverResponseIsFast ?
|
246
|
-
i18nString(
|
247
|
-
|
248
|
-
i18nString(
|
249
|
-
UIStrings.failedServerResponseTime, {PH1: i18n.TimeUtilities.millisToString(serverResponseTime)}),
|
250
|
+
i18nString(UIStrings.passingServerResponseTime, {PH1: millisToString(serverResponseTime)}) :
|
251
|
+
i18nString(UIStrings.failedServerResponseTime, {PH1: millisToString(serverResponseTime)}),
|
250
252
|
value: serverResponseIsFast
|
251
253
|
},
|
252
254
|
usesCompression: {
|
@@ -8,6 +8,7 @@ import type * as Protocol from '../../../generated/protocol.js';
|
|
8
8
|
import type * as Lantern from '../lantern/lantern.js';
|
9
9
|
|
10
10
|
import type * as File from './File.js';
|
11
|
+
import type {Milli} from './Timing.js';
|
11
12
|
|
12
13
|
export interface Configuration {
|
13
14
|
/**
|
@@ -83,6 +84,17 @@ export interface ParseOptions {
|
|
83
84
|
end: (id: string) => void,
|
84
85
|
};
|
85
86
|
lanternSettings?: Omit<Lantern.Types.Simulation.Settings, 'networkAnalysis'>;
|
87
|
+
/**
|
88
|
+
* Used when an Insight needs to format a time to string as part of its
|
89
|
+
* output. By default we use the i18n.TimeUtilities in DevTools but this
|
90
|
+
* enables it to be overridden, which is useful if you are consuming the trace
|
91
|
+
* engine outside of DevTools.
|
92
|
+
*/
|
93
|
+
insightTimeFormatters?: InsightTimeFormatters;
|
94
|
+
}
|
95
|
+
|
96
|
+
export interface InsightTimeFormatters {
|
97
|
+
milli: (x: Milli) => string;
|
86
98
|
}
|
87
99
|
|
88
100
|
export interface ResolveSourceMapParams {
|
@@ -22,7 +22,6 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
22
22
|
import * as NetworkForward from '../network/forward/forward.js';
|
23
23
|
import * as NetworkPanel from '../network/network.js';
|
24
24
|
import * as TimelinePanel from '../timeline/timeline.js';
|
25
|
-
import * as TimelineUtils from '../timeline/utils/utils.js';
|
26
25
|
|
27
26
|
import aiAssistancePanelStyles from './aiAssistancePanel.css.js';
|
28
27
|
import {
|
@@ -275,7 +274,7 @@ async function getEmptyStateSuggestions(
|
|
275
274
|
];
|
276
275
|
case AiAssistanceModel.ConversationType.PERFORMANCE_INSIGHT:
|
277
276
|
case AiAssistanceModel.ConversationType.PERFORMANCE_CALL_TREE: {
|
278
|
-
const focus = context?.getItem() as
|
277
|
+
const focus = context?.getItem() as AiAssistanceModel.AgentFocus | null;
|
279
278
|
if (focus?.data.type === 'call-tree') {
|
280
279
|
return [
|
281
280
|
{title: 'What\'s the purpose of this work?', jslogContext: 'performance-default'},
|
@@ -433,7 +432,7 @@ function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|null):
|
|
433
432
|
return new AiAssistanceModel.RequestContext(request, calculator);
|
434
433
|
}
|
435
434
|
|
436
|
-
function createPerformanceTraceContext(focus:
|
435
|
+
function createPerformanceTraceContext(focus: AiAssistanceModel.AgentFocus|null):
|
437
436
|
AiAssistanceModel.PerformanceTraceContext|null {
|
438
437
|
if (!focus) {
|
439
438
|
return null;
|
@@ -710,7 +709,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
710
709
|
this.#selectedRequest =
|
711
710
|
createRequestContext(UI.Context.Context.instance().flavor(SDK.NetworkRequest.NetworkRequest));
|
712
711
|
this.#selectedPerformanceTrace =
|
713
|
-
createPerformanceTraceContext(UI.Context.Context.instance().flavor(
|
712
|
+
createPerformanceTraceContext(UI.Context.Context.instance().flavor(AiAssistanceModel.AgentFocus));
|
714
713
|
this.#selectedFile = createFileContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UISourceCode));
|
715
714
|
this.#updateConversationState({agent: this.#conversationAgent});
|
716
715
|
|
@@ -723,7 +722,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
723
722
|
UI.Context.Context.instance().addFlavorChangeListener(
|
724
723
|
SDK.NetworkRequest.NetworkRequest, this.#handleNetworkRequestFlavorChange);
|
725
724
|
UI.Context.Context.instance().addFlavorChangeListener(
|
726
|
-
|
725
|
+
AiAssistanceModel.AgentFocus, this.#handlePerformanceTraceFlavorChange);
|
727
726
|
UI.Context.Context.instance().addFlavorChangeListener(
|
728
727
|
Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
|
729
728
|
|
@@ -760,7 +759,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
760
759
|
UI.Context.Context.instance().removeFlavorChangeListener(
|
761
760
|
SDK.NetworkRequest.NetworkRequest, this.#handleNetworkRequestFlavorChange);
|
762
761
|
UI.Context.Context.instance().removeFlavorChangeListener(
|
763
|
-
|
762
|
+
AiAssistanceModel.AgentFocus, this.#handlePerformanceTraceFlavorChange);
|
764
763
|
UI.Context.Context.instance().removeFlavorChangeListener(
|
765
764
|
Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
|
766
765
|
UI.ViewManager.ViewManager.instance().removeEventListener(
|
@@ -838,7 +837,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
838
837
|
};
|
839
838
|
|
840
839
|
#handlePerformanceTraceFlavorChange =
|
841
|
-
(ev: Common.EventTarget.EventTargetEvent<
|
840
|
+
(ev: Common.EventTarget.EventTargetEvent<AiAssistanceModel.AgentFocus>): void => {
|
842
841
|
if (this.#selectedPerformanceTrace?.getItem() === ev.data) {
|
843
842
|
return;
|
844
843
|
}
|
@@ -14,7 +14,6 @@ import * as SDK from '../../../core/sdk/sdk.js';
|
|
14
14
|
import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
|
15
15
|
import * as Workspace from '../../../models/workspace/workspace.js';
|
16
16
|
import * as ElementsPanel from '../../../panels/elements/elements.js';
|
17
|
-
import * as TimelineUtils from '../../../panels/timeline/utils/utils.js';
|
18
17
|
import * as PanelUtils from '../../../panels/utils/utils.js';
|
19
18
|
import * as Marked from '../../../third_party/marked/marked.js';
|
20
19
|
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
@@ -1040,7 +1039,7 @@ function renderContextIcon(context: AiAssistanceModel.ConversationContext<unknow
|
|
1040
1039
|
if (item instanceof Workspace.UISourceCode.UISourceCode) {
|
1041
1040
|
return PanelUtils.PanelUtils.getIconForSourceFile(item);
|
1042
1041
|
}
|
1043
|
-
if (item instanceof
|
1042
|
+
if (item instanceof AiAssistanceModel.AgentFocus) {
|
1044
1043
|
return html`<devtools-icon name="performance" title="Performance"></devtools-icon>`;
|
1045
1044
|
}
|
1046
1045
|
if (item instanceof SDK.DOMModel.DOMNode) {
|
@@ -3,6 +3,8 @@
|
|
3
3
|
// found in the LICENSE file.
|
4
4
|
|
5
5
|
import * as i18n from '../../../core/i18n/i18n.js';
|
6
|
+
import type * as Platform from '../../../core/platform/platform.js';
|
7
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
6
8
|
|
7
9
|
const UIStrings = {
|
8
10
|
/**
|
@@ -552,7 +554,10 @@ const UIStrings = {
|
|
552
554
|
const str_ = i18n.i18n.registerUIStrings('panels/application/components/BackForwardCacheStrings.ts', UIStrings);
|
553
555
|
const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
|
554
556
|
|
555
|
-
|
557
|
+
type NotRestoredReason =
|
558
|
+
Record<Protocol.Page.BackForwardCacheNotRestoredReason, {name: () => Platform.UIString.LocalizedString}>;
|
559
|
+
|
560
|
+
export const NotRestoredReasonDescription: NotRestoredReason = {
|
556
561
|
NotPrimaryMainFrame: {name: i18nLazyString(UIStrings.notMainFrame)},
|
557
562
|
BackForwardCacheDisabled: {name: i18nLazyString(UIStrings.backForwardCacheDisabled)},
|
558
563
|
RelatedActiveContentsExist: {name: i18nLazyString(UIStrings.relatedActiveContentsExist)},
|
@@ -567,6 +572,7 @@ export const NotRestoredReasonDescription = {
|
|
567
572
|
JavaScriptExecution: {name: i18nLazyString(UIStrings.JavaScriptExecution)},
|
568
573
|
RendererProcessKilled: {name: i18nLazyString(UIStrings.rendererProcessKilled)},
|
569
574
|
RendererProcessCrashed: {name: i18nLazyString(UIStrings.rendererProcessCrashed)},
|
575
|
+
// @ts-expect-error kept for backwards compatibly
|
570
576
|
GrantedMediaStreamAccess: {name: i18nLazyString(UIStrings.grantedMediaStreamAccess)},
|
571
577
|
CacheFlushed: {name: i18nLazyString(UIStrings.cacheFlushed)},
|
572
578
|
ServiceWorkerVersionActivation: {name: i18nLazyString(UIStrings.serviceWorkerVersionActivation)},
|
@@ -713,4 +719,4 @@ export const NotRestoredReasonDescription = {
|
|
713
719
|
{name: i18n.i18n.lockedLazyString('CacheLimitPrunedOnModerateMemoryPressure')},
|
714
720
|
CacheLimitPrunedOnCriticalMemoryPressure:
|
715
721
|
{name: i18n.i18n.lockedLazyString('CacheLimitPrunedOnCriticalMemoryPressure')},
|
716
|
-
};
|
722
|
+
} as const;
|
@@ -21,16 +21,16 @@ const UIStrings = {
|
|
21
21
|
/**
|
22
22
|
* @description Title for close button
|
23
23
|
*/
|
24
|
-
|
24
|
+
close: 'Close',
|
25
25
|
/**
|
26
26
|
* @description Activity based badge award notification text
|
27
27
|
* @example {Badge Title} PH1
|
28
28
|
*/
|
29
|
-
activityBasedBadgeAwardMessage: 'You earned the {PH1} badge! It
|
29
|
+
activityBasedBadgeAwardMessage: 'You earned the {PH1} badge! It’s been added to your Developer Profile.',
|
30
30
|
/**
|
31
31
|
* @description Action title for navigating to the badge settings in Google Developer Profile section
|
32
32
|
*/
|
33
|
-
|
33
|
+
manageSettings: 'Manage settings',
|
34
34
|
/**
|
35
35
|
* @description Action title for opening the Google Developer Program profile page of the user in a new tab
|
36
36
|
*/
|
@@ -55,7 +55,7 @@ const UIStrings = {
|
|
55
55
|
/**
|
56
56
|
* @description Action title for enabling the "Receive badges" setting
|
57
57
|
*/
|
58
|
-
receiveBadges: '
|
58
|
+
receiveBadges: 'Turn on badges',
|
59
59
|
/**
|
60
60
|
* @description Action title for creating a Google Developer Program profle
|
61
61
|
*/
|
@@ -103,10 +103,10 @@ const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement)
|
|
103
103
|
class="dismiss notification-button"
|
104
104
|
@click=${input.onCloseClick}
|
105
105
|
jslog=${VisualLogging.action('badge-notification.dismiss').track({click: true})}
|
106
|
-
aria-label=${i18nString(UIStrings.
|
106
|
+
aria-label=${i18nString(UIStrings.close)}
|
107
107
|
.iconName=${'cross'}
|
108
108
|
.variant=${Buttons.Button.Variant.ICON}
|
109
|
-
.title=${i18nString(UIStrings.
|
109
|
+
.title=${i18nString(UIStrings.close)}
|
110
110
|
.inverseColorTheme=${true}
|
111
111
|
></devtools-button>`;
|
112
112
|
|
@@ -114,7 +114,7 @@ const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement)
|
|
114
114
|
<style>${badgeNotificationStyles}</style>
|
115
115
|
<div class="container">
|
116
116
|
<div class="badge-container">
|
117
|
-
<img class="badge-image" src=${input.imageUri}>
|
117
|
+
<img class="badge-image" role="presentation" src=${input.imageUri}>
|
118
118
|
</div>
|
119
119
|
<div class="action-and-text-container">
|
120
120
|
<div class="label-container">
|
@@ -145,6 +145,8 @@ export class BadgeNotification extends UI.Widget.Widget {
|
|
145
145
|
super(element);
|
146
146
|
this.#view = view;
|
147
147
|
|
148
|
+
// eslint-disable-next-line
|
149
|
+
this.contentElement.role = 'alert';
|
148
150
|
this.markAsRoot();
|
149
151
|
}
|
150
152
|
|
@@ -240,7 +242,7 @@ export class BadgeNotification extends UI.Widget.Widget {
|
|
240
242
|
message: i18nString(UIStrings.activityBasedBadgeAwardMessage, {PH1: badge.title}),
|
241
243
|
actions: [
|
242
244
|
{
|
243
|
-
label: i18nString(UIStrings.
|
245
|
+
label: i18nString(UIStrings.manageSettings),
|
244
246
|
onClick: () => {
|
245
247
|
this.#close();
|
246
248
|
revealBadgeSettings();
|