chrome-devtools-frontend 1.0.1643099 → 1.0.1645245
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/eslint.config.mjs +3 -1
- package/extension-api/ExtensionAPI.d.ts +83 -12
- package/front_end/core/host/UserMetrics.ts +3 -3
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -3
- package/front_end/core/sdk/ConsoleModel.ts +4 -0
- package/front_end/core/sdk/NetworkRequest.ts +12 -1
- package/front_end/core/sdk/SourceMap.ts +15 -18
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -2
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +37 -0
- package/front_end/entrypoints/main/MainImpl.ts +0 -6
- package/front_end/generated/SupportedCSSProperties.js +4 -2
- package/front_end/models/ai_assistance/AiAgent2.ts +23 -12
- package/front_end/models/ai_assistance/README.md +5 -4
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +22 -16
- package/front_end/models/ai_assistance/agents/AiAgent.ts +19 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +5 -5
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -94
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +25 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +37 -0
- package/front_end/models/ai_assistance/agents/README.md +57 -0
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +54 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -2
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +31 -3
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +12 -21
- package/front_end/models/ai_assistance/tools/GetStyles.ts +19 -12
- package/front_end/models/ai_assistance/tools/README.md +45 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +78 -9
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +21 -5
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +6 -9
- package/front_end/models/bindings/DefaultScriptMapping.ts +2 -1
- package/front_end/models/bindings/SymbolizedError.ts +45 -35
- package/front_end/models/extensions/ExtensionAPI.ts +138 -47
- package/front_end/models/har/Importer.ts +1 -0
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +18 -2
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +4 -0
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +12 -2
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +58 -52
- package/front_end/models/stack_trace/StackTrace.ts +7 -0
- package/front_end/models/stack_trace/StackTraceImpl.ts +13 -4
- package/front_end/models/stack_trace/StackTraceModel.ts +43 -9
- package/front_end/models/trace/Styles.ts +29 -7
- package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +33 -4
- package/front_end/models/trace/helpers/Timing.ts +10 -0
- package/front_end/models/trace/types/TraceEvents.ts +22 -2
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +2 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +9 -2
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +16 -0
- package/front_end/panels/application/ApplicationPanelSidebar.ts +83 -0
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +39 -0
- package/front_end/panels/application/CookieItemsView.ts +2 -2
- package/front_end/panels/application/ServiceWorkersView.ts +2 -2
- package/front_end/panels/application/WebMCPView.ts +0 -1
- package/front_end/panels/application/components/BackForwardCacheView.ts +1 -2
- package/front_end/panels/application/resourcesSidebar.css +11 -0
- package/front_end/panels/console/ConsoleView.ts +6 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +46 -213
- package/front_end/panels/console/SymbolizedErrorWidget.ts +14 -8
- package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +0 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +0 -2
- package/front_end/panels/elements/PropertyRenderer.ts +0 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +9 -2
- package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
- package/front_end/panels/issues/AffectedSourcesView.ts +1 -1
- package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +0 -1
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +10 -0
- package/front_end/panels/network/NetworkDataGridNode.ts +1 -2
- package/front_end/panels/network/NetworkLogView.ts +34 -7
- package/front_end/panels/profiler/HeapProfileView.ts +0 -1
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +0 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +1 -1
- package/front_end/panels/settings/components/SyncSection.ts +1 -1
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -0
- package/front_end/panels/sources/SourcesPanel.ts +2 -1
- package/front_end/panels/timeline/TimelineFlameChartView.ts +5 -4
- package/front_end/panels/timeline/TimelinePanel.ts +7 -0
- package/front_end/panels/timeline/TimelineUIUtils.ts +13 -14
- package/front_end/panels/timeline/TimingsTrackAppender.ts +7 -5
- package/front_end/panels/timeline/components/LayoutShiftDetails.ts +0 -1
- package/front_end/panels/timeline/components/NetworkRequestDetails.ts +0 -2
- package/front_end/panels/timeline/components/insights/ForcedReflow.ts +0 -1
- package/front_end/panels/timeline/components/insights/NodeLink.ts +0 -1
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +2 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/helpers/OpenInNewTab.ts +3 -3
- package/front_end/ui/kit/link/Link.ts +16 -2
- package/front_end/ui/legacy/InspectorDrawerView.ts +14 -5
- package/front_end/ui/legacy/InspectorView.ts +4 -1
- package/front_end/ui/legacy/PlusButton.ts +6 -1
- package/front_end/ui/legacy/StackedPane.ts +229 -0
- package/front_end/ui/legacy/ViewManager.ts +59 -169
- package/front_end/ui/legacy/Widget.ts +19 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +95 -31
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +0 -1
- package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -16
- package/front_end/ui/legacy/legacy.ts +3 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/package.json +1 -1
package/eslint.config.mjs
CHANGED
|
@@ -721,7 +721,8 @@ export default defineConfig([
|
|
|
721
721
|
'test/**/*.ts',
|
|
722
722
|
'**/testing/*.ts',
|
|
723
723
|
'scripts/eslint_rules/test/**/*',
|
|
724
|
-
'extensions/cxx_debugging/e2e
|
|
724
|
+
'extensions/cxx_debugging/e2e/**/*.ts',
|
|
725
|
+
'extensions/cxx_debugging/tests/**/*.ts',
|
|
725
726
|
],
|
|
726
727
|
|
|
727
728
|
rules: {
|
|
@@ -750,6 +751,7 @@ export default defineConfig([
|
|
|
750
751
|
],
|
|
751
752
|
|
|
752
753
|
'@devtools/check-test-definitions': 'error',
|
|
754
|
+
'@devtools/prefer-chai-assert': 'error',
|
|
753
755
|
'@devtools/no-assert-strict-equal-for-arrays-and-objects': 'error',
|
|
754
756
|
'@devtools/no-assert-deep-strict-equal': 'error',
|
|
755
757
|
'@devtools/no-assert-equal': 'error',
|
|
@@ -19,8 +19,35 @@ export namespace Chrome {
|
|
|
19
19
|
*/
|
|
20
20
|
readonly buildId?: string;
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Returns the `content` and `encoding` of the resource. If a `callback`
|
|
24
|
+
* is provided, it is invoked with the `content` and `encoding` and the
|
|
25
|
+
* method returns `void`. If no `callback` is provided, the method returns
|
|
26
|
+
* a `Promise`.
|
|
27
|
+
*
|
|
28
|
+
* @param callback Optional callback to be invoked with the content and
|
|
29
|
+
* encoding.
|
|
30
|
+
* @returns A Promise that resolves to an object containing the content
|
|
31
|
+
* and encoding if no callback is provided, otherwise void. Rejects with
|
|
32
|
+
* an error object on failure.
|
|
33
|
+
*/
|
|
34
|
+
getContent(): Promise<{content: string, encoding: string}>;
|
|
22
35
|
getContent(callback: (content: string, encoding: string) => unknown): void;
|
|
23
|
-
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Sets the content of the resource. If a `callback` is provided, it is
|
|
39
|
+
* invoked when the content is set and the method returns `void`. If no
|
|
40
|
+
* `callback` is provided, the method returns a `Promise`.
|
|
41
|
+
*
|
|
42
|
+
* @param content The new content of the resource.
|
|
43
|
+
* @param commit Whether to commit the changes.
|
|
44
|
+
* @param callback Optional callback to be invoked when the content is
|
|
45
|
+
* set.
|
|
46
|
+
* @returns A Promise that resolves when the content is set if no callback
|
|
47
|
+
* is provided, otherwise void. Rejects with an error object on failure.
|
|
48
|
+
*/
|
|
49
|
+
setContent(content: string, commit: boolean): Promise<void>;
|
|
50
|
+
setContent(content: string, commit: boolean, callback: (error?: object) => unknown): void;
|
|
24
51
|
/**
|
|
25
52
|
* Augments this resource's scopes information based on the list of {@link NamedFunctionRange}s
|
|
26
53
|
* for improved debuggability and function naming.
|
|
@@ -40,18 +67,62 @@ export namespace Chrome {
|
|
|
40
67
|
onResourceAdded: EventSink<(resource: Resource) => unknown>;
|
|
41
68
|
onResourceContentCommitted: EventSink<(resource: Resource, content: string) => unknown>;
|
|
42
69
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Evaluates a JavaScript expression in the context of the inspected page.
|
|
72
|
+
*
|
|
73
|
+
* If a `callback` is provided, it is invoked with the result and
|
|
74
|
+
* exception information and the method returns `void`. If no `callback`
|
|
75
|
+
* is provided, the method returns a `Promise`.
|
|
76
|
+
*
|
|
77
|
+
* @template E The type of the value that the Promise resolves to.
|
|
78
|
+
* @param expression The JavaScript expression to evaluate.
|
|
79
|
+
* @param optionsOrCallback Optional options for evaluation, or a callback
|
|
80
|
+
* function.
|
|
81
|
+
* @param callback Optional callback to be invoked with the evaluation
|
|
82
|
+
* result and exception information.
|
|
83
|
+
* @returns A Promise that resolves to the result if no callback is
|
|
84
|
+
* provided, otherwise void. Rejects with an error object on failure.
|
|
85
|
+
*/
|
|
86
|
+
eval<E = unknown>(expression: string, options?: {
|
|
87
|
+
scriptExecutionContext?: string,
|
|
88
|
+
frameURL?: string,
|
|
89
|
+
useContentScriptContext?: boolean,
|
|
90
|
+
}): Promise<E>;
|
|
91
|
+
eval(expression: string,
|
|
92
|
+
optionsOrCallback: {scriptExecutionContext?: string, frameURL?: string, useContentScriptContext?: boolean}|
|
|
93
|
+
undefined|((result: unknown, exceptioninfo: {
|
|
94
|
+
code: string,
|
|
95
|
+
description: string,
|
|
96
|
+
details: unknown[],
|
|
97
|
+
isError: boolean,
|
|
98
|
+
isException: boolean,
|
|
99
|
+
value: string,
|
|
100
|
+
}) => unknown),
|
|
101
|
+
callback?: (result: unknown, exceptioninfo: {
|
|
102
|
+
code: string,
|
|
103
|
+
description: string,
|
|
104
|
+
details: unknown[],
|
|
105
|
+
isError: boolean,
|
|
106
|
+
isException: boolean,
|
|
107
|
+
value: string,
|
|
108
|
+
}) => unknown): void;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Retrieves all resources within the inspected window.
|
|
112
|
+
*
|
|
113
|
+
* If a `callback` is provided, it is invoked with the array of resources
|
|
114
|
+
* and the method returns `void`. If no `callback` is provided, the method
|
|
115
|
+
* returns a `Promise`.
|
|
116
|
+
*
|
|
117
|
+
* @param callback Optional callback to be invoked with the array of
|
|
118
|
+
* resources.
|
|
119
|
+
* @returns A Promise that resolves to an array of resources if no
|
|
120
|
+
* callback is provided, otherwise void. Rejects with an error object on
|
|
121
|
+
* failure.
|
|
122
|
+
*/
|
|
123
|
+
getResources(): Promise<Resource[]>;
|
|
54
124
|
getResources(callback: (resources: Resource[]) => unknown): void;
|
|
125
|
+
|
|
55
126
|
reload(reloadOptions?: {ignoreCache?: boolean, injectedScript?: string, userAgent?: string}): void;
|
|
56
127
|
}
|
|
57
128
|
|
|
@@ -496,8 +496,9 @@ export enum Action {
|
|
|
496
496
|
AiCodeGenerationRequestTriggeredFromSources = 205,
|
|
497
497
|
AiCodeCompletionFreCompletedFromConsole = 206,
|
|
498
498
|
AiCodeCompletionFreCompletedFromSources = 207,
|
|
499
|
-
|
|
500
|
-
|
|
499
|
+
AiAssistanceOpenedFromApplicationPanelFloatingButton = 208,
|
|
500
|
+
AiAssistanceOpenedFromApplicationPanel = 209,
|
|
501
|
+
MAX_VALUE = 210,
|
|
501
502
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
502
503
|
}
|
|
503
504
|
|
|
@@ -767,7 +768,6 @@ export enum DevtoolsExperiments {
|
|
|
767
768
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
768
769
|
'protocol-monitor' = 13,
|
|
769
770
|
'instrumentation-breakpoints' = 61,
|
|
770
|
-
'use-source-map-scopes' = 76,
|
|
771
771
|
'durable-messages' = 110,
|
|
772
772
|
'jpeg-xl' = 111,
|
|
773
773
|
'plus-button' = 112,
|
|
@@ -6,7 +6,6 @@ export enum ExperimentName {
|
|
|
6
6
|
ALL = '*',
|
|
7
7
|
PROTOCOL_MONITOR = 'protocol-monitor',
|
|
8
8
|
INSTRUMENTATION_BREAKPOINTS = 'instrumentation-breakpoints',
|
|
9
|
-
USE_SOURCE_MAP_SCOPES = 'use-source-map-scopes',
|
|
10
9
|
DURABLE_MESSAGES = 'durable-messages',
|
|
11
10
|
JPEG_XL = 'jpeg-xl',
|
|
12
11
|
PLUS_BUTTON = 'plus-button',
|
|
@@ -561,9 +561,8 @@ export class ColorMatcher extends matcherBase(ColorMatch) {
|
|
|
561
561
|
const colorText = args.length >= 2 ? matching.getComputedTextRange(args[0], args[args.length - 1]) : '';
|
|
562
562
|
// colorText holds the fully substituted parenthesized expression, so colorFunc + colorText is the color
|
|
563
563
|
// function call.
|
|
564
|
-
const isRelativeColorSyntax =
|
|
565
|
-
colorText.match(/^[^)]*\(\W*from\W+/) && !matching.hasUnresolvedSubstitutions(node)
|
|
566
|
-
CSS.supports('color', colorFunc + colorText));
|
|
564
|
+
const isRelativeColorSyntax =
|
|
565
|
+
Boolean(colorText.match(/^[^)]*\(\W*from\W+/) && !matching.hasUnresolvedSubstitutions(node));
|
|
567
566
|
if (!isRelativeColorSyntax) {
|
|
568
567
|
return new ColorMatch(text, node);
|
|
569
568
|
}
|
|
@@ -547,6 +547,7 @@ export interface ConsoleMessageDetails {
|
|
|
547
547
|
context?: string;
|
|
548
548
|
affectedResources?: AffectedResources;
|
|
549
549
|
category?: Protocol.Log.LogEntryCategory;
|
|
550
|
+
exceptionDetails?: Protocol.Runtime.ExceptionDetails;
|
|
550
551
|
}
|
|
551
552
|
|
|
552
553
|
export class ConsoleMessage {
|
|
@@ -570,6 +571,7 @@ export class ConsoleMessage {
|
|
|
570
571
|
#exceptionId?: number = undefined;
|
|
571
572
|
#affectedResources?: AffectedResources;
|
|
572
573
|
category?: Protocol.Log.LogEntryCategory;
|
|
574
|
+
readonly exceptionDetails?: Protocol.Runtime.ExceptionDetails;
|
|
573
575
|
|
|
574
576
|
/**
|
|
575
577
|
* The parent frame of the `console.log` call of logpoints or conditional breakpoints
|
|
@@ -600,6 +602,7 @@ export class ConsoleMessage {
|
|
|
600
602
|
this.workerId = details?.workerId;
|
|
601
603
|
this.#affectedResources = details?.affectedResources;
|
|
602
604
|
this.category = details?.category;
|
|
605
|
+
this.exceptionDetails = details?.exceptionDetails;
|
|
603
606
|
|
|
604
607
|
if (!this.#executionContextId && this.#runtimeModel) {
|
|
605
608
|
if (this.scriptId) {
|
|
@@ -646,6 +649,7 @@ export class ConsoleMessage {
|
|
|
646
649
|
executionContextId: exceptionDetails.executionContextId,
|
|
647
650
|
scriptId: exceptionDetails.scriptId,
|
|
648
651
|
affectedResources,
|
|
652
|
+
exceptionDetails,
|
|
649
653
|
};
|
|
650
654
|
return new ConsoleMessage(
|
|
651
655
|
runtimeModel, Protocol.Log.LogEntrySource.Javascript, Protocol.Log.LogEntryLevel.Error,
|
|
@@ -299,6 +299,10 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
|
299
299
|
#contentDataProvider?: () => Promise<TextUtils.ContentData.ContentDataOrError>;
|
|
300
300
|
#isSameSite: boolean|null = null;
|
|
301
301
|
#wasIntercepted = false;
|
|
302
|
+
/**
|
|
303
|
+
* Whether this request was imported from a HAR file.
|
|
304
|
+
*/
|
|
305
|
+
#isImportedHar = false;
|
|
302
306
|
#associatedData = new Map<string, object>();
|
|
303
307
|
#hasOverriddenContent = false;
|
|
304
308
|
#hasThirdPartyCookiePhaseoutIssue = false;
|
|
@@ -1148,6 +1152,14 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
|
|
|
1148
1152
|
this.#wasIntercepted = wasIntercepted;
|
|
1149
1153
|
}
|
|
1150
1154
|
|
|
1155
|
+
isImportedHar(): boolean {
|
|
1156
|
+
return this.#isImportedHar;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
setIsImportedHar(isImportedHar: boolean): void {
|
|
1160
|
+
this.#isImportedHar = isImportedHar;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1151
1163
|
setEarlyHintsHeaders(headers: NameValue[]): void {
|
|
1152
1164
|
this.earlyHintsHeaders = headers;
|
|
1153
1165
|
}
|
|
@@ -1908,7 +1920,6 @@ export interface EventTypes {
|
|
|
1908
1920
|
[Events.RESPONSE_HEADERS_CHANGED]: void;
|
|
1909
1921
|
[Events.WEBSOCKET_FRAME_ADDED]: WebSocketFrame;
|
|
1910
1922
|
[Events.DIRECTSOCKET_CHUNK_ADDED]: DirectSocketChunk;
|
|
1911
|
-
[Events.DIRECTSOCKET_CHUNK_ADDED]: DirectSocketChunk;
|
|
1912
1923
|
[Events.EVENT_SOURCE_MESSAGE_ADDED]: EventSourceMessage;
|
|
1913
1924
|
[Events.TRUST_TOKEN_RESULT_ADDED]: void;
|
|
1914
1925
|
}
|
|
@@ -6,7 +6,6 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
|
6
6
|
import * as ScopesCodec from '../../third_party/source-map-scopes-codec/source-map-scopes-codec.js';
|
|
7
7
|
import * as Common from '../common/common.js';
|
|
8
8
|
import * as Platform from '../platform/platform.js';
|
|
9
|
-
import * as Root from '../root/root.js';
|
|
10
9
|
|
|
11
10
|
import type {CallFrame, ScopeChainEntry} from './DebuggerModel.js';
|
|
12
11
|
import {scopeTreeForScript} from './ScopeTreeCache.js';
|
|
@@ -584,23 +583,21 @@ export class SourceMap {
|
|
|
584
583
|
lineNumber, columnNumber, sourceIndex, sourceURL, sourceLineNumber, sourceColumnNumber, names[nameIndex]));
|
|
585
584
|
}
|
|
586
585
|
|
|
587
|
-
if (
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
this.#scopesInfo.addOriginalScopes(new Array(map.sources.length).fill(null));
|
|
603
|
-
}
|
|
586
|
+
if (!this.#scopesInfo) {
|
|
587
|
+
this.#scopesInfo = new SourceMapScopesInfo(this, {scopes: [], ranges: []});
|
|
588
|
+
}
|
|
589
|
+
if (map.scopes) {
|
|
590
|
+
const {scopes, ranges} = ScopesCodec.decode(
|
|
591
|
+
map as ScopesCodec.SourceMapJson,
|
|
592
|
+
{mode: ScopesCodec.DecodeMode.LAX, generatedOffset: {line: baseLineNumber, column: baseColumnNumber}});
|
|
593
|
+
this.#scopesInfo.addOriginalScopes(scopes);
|
|
594
|
+
this.#scopesInfo.addGeneratedRanges(ranges);
|
|
595
|
+
} else if (map.x_com_bloomberg_sourcesFunctionMappings) {
|
|
596
|
+
const originalScopes = this.parseBloombergScopes(map);
|
|
597
|
+
this.#scopesInfo.addOriginalScopes(originalScopes);
|
|
598
|
+
} else {
|
|
599
|
+
// Keep the OriginalScope[] tree array consistent with sources.
|
|
600
|
+
this.#scopesInfo.addOriginalScopes(new Array(map.sources.length).fill(null));
|
|
604
601
|
}
|
|
605
602
|
}
|
|
606
603
|
|
|
@@ -593,8 +593,6 @@ async function init(): Promise<void> {
|
|
|
593
593
|
|
|
594
594
|
safeRegisterExperiment(
|
|
595
595
|
Root.ExperimentNames.ExperimentName.INSTRUMENTATION_BREAKPOINTS, 'Enable instrumentation breakpoints');
|
|
596
|
-
safeRegisterExperiment(
|
|
597
|
-
Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES, 'Use scope information from source maps');
|
|
598
596
|
safeRegisterExperiment(Root.ExperimentNames.ExperimentName.PROTOCOL_MONITOR, 'Protocol Monitor');
|
|
599
597
|
|
|
600
598
|
const hostUnsyncedStorage: Common.Settings.SettingsBackingStore = {
|
|
@@ -247,8 +247,6 @@ async function init(): Promise<void> {
|
|
|
247
247
|
// Register necessary experiments to avoid "Unknown experiment" errors.
|
|
248
248
|
Root.Runtime.experiments.register(
|
|
249
249
|
Root.ExperimentNames.ExperimentName.INSTRUMENTATION_BREAKPOINTS, 'Enable instrumentation breakpoints');
|
|
250
|
-
Root.Runtime.experiments.register(
|
|
251
|
-
Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES, 'Use scope information from source maps');
|
|
252
250
|
Root.Runtime.experiments.register(Root.ExperimentNames.ExperimentName.PROTOCOL_MONITOR, 'Protocol Monitor');
|
|
253
251
|
|
|
254
252
|
const WINDOW_LOCAL_STORAGE: Common.Settings.SettingsBackingStore = {
|
|
@@ -2740,6 +2740,8 @@ export abstract class HeapSnapshot {
|
|
|
2740
2740
|
const nodeAId = baseIds[i];
|
|
2741
2741
|
if (nodeAId < nodeB.id()) {
|
|
2742
2742
|
diff.deletedIndexes.push(baseIndexes[i]);
|
|
2743
|
+
diff.deletedIds.push(nodeAId);
|
|
2744
|
+
diff.deletedSelfSizes.push(baseSelfSizes[i]);
|
|
2743
2745
|
diff.removedCount++;
|
|
2744
2746
|
diff.removedSize += baseSelfSizes[i];
|
|
2745
2747
|
++i;
|
|
@@ -2747,6 +2749,8 @@ export abstract class HeapSnapshot {
|
|
|
2747
2749
|
nodeAId >
|
|
2748
2750
|
nodeB.id()) { // Native nodes(e.g. dom groups) may have ids less than max JS object id in the base snapshot
|
|
2749
2751
|
diff.addedIndexes.push(indexes[j]);
|
|
2752
|
+
diff.addedIds.push(nodeB.id());
|
|
2753
|
+
diff.addedSelfSizes.push(nodeB.selfSize());
|
|
2750
2754
|
diff.addedCount++;
|
|
2751
2755
|
diff.addedSize += nodeB.selfSize();
|
|
2752
2756
|
nodeB.nodeIndex = indexes[++j];
|
|
@@ -2757,12 +2761,16 @@ export abstract class HeapSnapshot {
|
|
|
2757
2761
|
}
|
|
2758
2762
|
while (i < l) {
|
|
2759
2763
|
diff.deletedIndexes.push(baseIndexes[i]);
|
|
2764
|
+
diff.deletedIds.push(baseIds[i]);
|
|
2765
|
+
diff.deletedSelfSizes.push(baseSelfSizes[i]);
|
|
2760
2766
|
diff.removedCount++;
|
|
2761
2767
|
diff.removedSize += baseSelfSizes[i];
|
|
2762
2768
|
++i;
|
|
2763
2769
|
}
|
|
2764
2770
|
while (j < m) {
|
|
2765
2771
|
diff.addedIndexes.push(indexes[j]);
|
|
2772
|
+
diff.addedIds.push(nodeB.id());
|
|
2773
|
+
diff.addedSelfSizes.push(nodeB.selfSize());
|
|
2766
2774
|
diff.addedCount++;
|
|
2767
2775
|
diff.addedSize += nodeB.selfSize();
|
|
2768
2776
|
nodeB.nodeIndex = indexes[++j];
|
|
@@ -2975,6 +2983,35 @@ export abstract class HeapSnapshot {
|
|
|
2975
2983
|
return {paths, limitsReached};
|
|
2976
2984
|
}
|
|
2977
2985
|
|
|
2986
|
+
getDominatorsOf(nodeIndex: number): HeapSnapshotModel.HeapSnapshotModel.DominatorChain {
|
|
2987
|
+
const chain: HeapSnapshotModel.HeapSnapshotModel.DominatorNode[] = [];
|
|
2988
|
+
let currentIndex = nodeIndex;
|
|
2989
|
+
const rootIndex = this.rootNodeIndex;
|
|
2990
|
+
|
|
2991
|
+
while (currentIndex !== undefined) {
|
|
2992
|
+
const node = this.createNode(currentIndex);
|
|
2993
|
+
chain.push({
|
|
2994
|
+
nodeId: node.id(),
|
|
2995
|
+
nodeIndex: currentIndex,
|
|
2996
|
+
nodeName: node.name(),
|
|
2997
|
+
retainedSize: node.retainedSize(),
|
|
2998
|
+
selfSize: node.selfSize(),
|
|
2999
|
+
});
|
|
3000
|
+
|
|
3001
|
+
if (currentIndex === rootIndex) {
|
|
3002
|
+
break;
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
const nextIndex = node.dominatorIndex();
|
|
3006
|
+
if (nextIndex === currentIndex) {
|
|
3007
|
+
break;
|
|
3008
|
+
}
|
|
3009
|
+
currentIndex = nextIndex;
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
return chain;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2978
3015
|
createAddedNodesProvider(baseSnapshotId: number, classKey: string): HeapSnapshotNodesProvider {
|
|
2979
3016
|
const snapshotDiff = this.#snapshotDiffs[baseSnapshotId];
|
|
2980
3017
|
const diffForClass = snapshotDiff[classKey];
|
|
@@ -365,8 +365,6 @@ export class MainImpl {
|
|
|
365
365
|
// Debugging
|
|
366
366
|
Root.Runtime.experiments.register(
|
|
367
367
|
Root.ExperimentNames.ExperimentName.INSTRUMENTATION_BREAKPOINTS, 'Instrumentation breakpoints');
|
|
368
|
-
Root.Runtime.experiments.register(
|
|
369
|
-
Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES, 'Use scope information from source maps');
|
|
370
368
|
|
|
371
369
|
Root.Runtime.experiments.registerHostExperiment({
|
|
372
370
|
name: Root.ExperimentNames.ExperimentName.DURABLE_MESSAGES,
|
|
@@ -392,10 +390,6 @@ export class MainImpl {
|
|
|
392
390
|
requiresChromeRestart: false,
|
|
393
391
|
});
|
|
394
392
|
|
|
395
|
-
Root.Runtime.experiments.enableExperimentsByDefault([
|
|
396
|
-
Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES,
|
|
397
|
-
]);
|
|
398
|
-
|
|
399
393
|
const enabledExperiments = Root.Runtime.Runtime.queryParam('enabledExperiments');
|
|
400
394
|
if (enabledExperiments) {
|
|
401
395
|
Root.Runtime.experiments.setServerEnabledExperiments(enabledExperiments.split(';'));
|
|
@@ -3860,7 +3860,8 @@ export const generatedProperties = [
|
|
|
3860
3860
|
{
|
|
3861
3861
|
"keywords": [
|
|
3862
3862
|
"auto",
|
|
3863
|
-
"none"
|
|
3863
|
+
"none",
|
|
3864
|
+
"normal"
|
|
3864
3865
|
],
|
|
3865
3866
|
"name": "position-anchor"
|
|
3866
3867
|
},
|
|
@@ -6987,7 +6988,8 @@ export const generatedPropertyValues = {
|
|
|
6987
6988
|
"position-anchor": {
|
|
6988
6989
|
"values": [
|
|
6989
6990
|
"auto",
|
|
6990
|
-
"none"
|
|
6991
|
+
"none",
|
|
6992
|
+
"normal"
|
|
6991
6993
|
]
|
|
6992
6994
|
},
|
|
6993
6995
|
"position-area": {
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Host from '../../core/host/host.js';
|
|
6
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
6
7
|
|
|
7
8
|
import {
|
|
8
9
|
AiAgent,
|
|
10
|
+
type AllowedOriginResult,
|
|
9
11
|
type ContextResponse,
|
|
10
12
|
type ConversationContext,
|
|
11
13
|
type MultimodalInputType,
|
|
@@ -19,7 +21,7 @@ import {debugLog} from './debug.js';
|
|
|
19
21
|
import {ExtensionScope} from './ExtensionScope.js';
|
|
20
22
|
import type {Skill, SkillName} from './skills/Skill.js';
|
|
21
23
|
import {SKILLS} from './skills/SkillRegistry.js';
|
|
22
|
-
import type {Tool} from './tools/Tool.js';
|
|
24
|
+
import type {AllToolsContext, Tool, ToolArgs} from './tools/Tool.js';
|
|
23
25
|
import {ToolRegistry} from './tools/ToolRegistry.js';
|
|
24
26
|
|
|
25
27
|
const SKILL_DISPLAY_NAMES: Record<SkillName, string> = {
|
|
@@ -35,6 +37,7 @@ export class AiAgent2 extends AiAgent<unknown> {
|
|
|
35
37
|
#skillsInjected = false;
|
|
36
38
|
#changes = new ChangeManager();
|
|
37
39
|
#execJs: typeof executeJsCode;
|
|
40
|
+
readonly #allowedOrigin?: () => AllowedOriginResult;
|
|
38
41
|
|
|
39
42
|
get options(): RequestOptions {
|
|
40
43
|
return {};
|
|
@@ -46,6 +49,7 @@ export class AiAgent2 extends AiAgent<unknown> {
|
|
|
46
49
|
constructor(opts: ExecuteJsAgentOptions) {
|
|
47
50
|
super(opts);
|
|
48
51
|
this.#execJs = opts.execJs ?? executeJsCode;
|
|
52
|
+
this.#allowedOrigin = opts.allowedOrigin;
|
|
49
53
|
this.#declaredTools.add('learnSkills');
|
|
50
54
|
const skillsList = Object.keys(SKILLS).join(', ');
|
|
51
55
|
this.declareFunction<{skills: SkillName[]}>('learnSkills', {
|
|
@@ -169,7 +173,7 @@ User query: ${enhancedQuery}`;
|
|
|
169
173
|
* Declares a tool to be available to the agent model, verifying first that
|
|
170
174
|
* it hasn't already been declared to prevent duplicate declaration errors.
|
|
171
175
|
*/
|
|
172
|
-
#declareTool(tool: Tool): void {
|
|
176
|
+
#declareTool(tool: Tool<ToolArgs, unknown, AllToolsContext>): void {
|
|
173
177
|
if (this.#declaredTools.has(tool.name)) {
|
|
174
178
|
debugLog(`AiAgent2: Tool ${tool.name} is already declared`);
|
|
175
179
|
return;
|
|
@@ -179,19 +183,26 @@ User query: ${enhancedQuery}`;
|
|
|
179
183
|
description: tool.description,
|
|
180
184
|
parameters: tool.parameters,
|
|
181
185
|
displayInfoFromArgs: tool.displayInfoFromArgs,
|
|
182
|
-
handler: (args, options) =>
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
handler: (args, options) => {
|
|
187
|
+
const context: AllToolsContext = {
|
|
188
|
+
conversationContext: this.context ?? null,
|
|
189
|
+
changeManager: this.#changes,
|
|
190
|
+
createExtensionScope: this.#createExtensionScope.bind(this),
|
|
191
|
+
execJs: this.#execJs,
|
|
192
|
+
getExecutionContextNode: () => this.context instanceof DOMNodeContext ? this.context.getItem() : null,
|
|
193
|
+
getTarget: () => SDK.TargetManager.TargetManager.instance().primaryPageTarget(),
|
|
194
|
+
getEstablishedOrigin: () => this.#getConversationOrigin(),
|
|
195
|
+
};
|
|
196
|
+
return tool.handler(args, context, options);
|
|
197
|
+
},
|
|
192
198
|
});
|
|
193
199
|
}
|
|
194
200
|
|
|
201
|
+
#getConversationOrigin(): string|undefined {
|
|
202
|
+
const allowed = this.#allowedOrigin?.();
|
|
203
|
+
return allowed && 'origin' in allowed ? allowed.origin : undefined;
|
|
204
|
+
}
|
|
205
|
+
|
|
195
206
|
get activeSkills(): Set<SkillName> {
|
|
196
207
|
return this.#activeSkills;
|
|
197
208
|
}
|
|
@@ -24,7 +24,7 @@ To deal with the work to take an object that is the AI agent's context and turn
|
|
|
24
24
|
|
|
25
25
|
## Future Architecture (V2) - WIP
|
|
26
26
|
|
|
27
|
-
We are
|
|
27
|
+
We are migrating the DevTools AI Assistance from a siloed multi-agent architecture to a unified, skill-based single-agent architecture (`AIAgent2`).
|
|
28
28
|
|
|
29
29
|
In this new architecture:
|
|
30
30
|
- A single agent (`AIAgent2`) handles multiple domains.
|
|
@@ -36,15 +36,16 @@ This work is currently in progress and behind a feature flag.
|
|
|
36
36
|
### Skills Build System
|
|
37
37
|
|
|
38
38
|
To support dynamic loading of skills, we generate JavaScript files from Markdown files containing skill definitions.
|
|
39
|
-
We use a nested `BUILD.gn` file in the `skills/` subdirectory specifically for this purpose. This ensures that GN's `target_gen_dir` points to `gen/front_end/models/ai_assistance/skills/`, placing the generated `.skill.js` files in the same relative structure as their source `.md` files. This allows TypeScript files in the `skills/` directory (like `map.ts`) to import the generated files using relative paths (e.g., `./styling.skill.js`) seamlessly.
|
|
39
|
+
We use a nested `BUILD.gn` file in the `skills/` subdirectory specifically for this purpose. This ensures that GN's `target_gen_dir` points to `gen/front_end/models/ai_assistance/skills/`, placing the generated `.skill.js` files in the same relative structure as their source `.md` files. This allows TypeScript files in the `skills/` directory (like `map.ts`) to import the generated files using relative paths (e.g., `./styling.skill.js`) seamlessly. See the [Skills README](skills/README.md) for full details.
|
|
40
40
|
|
|
41
41
|
### Tools and ToolRegistry
|
|
42
42
|
|
|
43
43
|
To support skills requiring execution of code or fetching page state (like computed styles), the architecture defines **Tools** in the `tools/` directory.
|
|
44
44
|
|
|
45
45
|
- **BaseTool**: A non-generic base interface capturing tool metadata (`name`, `description`, `parameters`). This acts as the type-erased representation for generic registry storage and fallback string lookups.
|
|
46
|
-
- **Tool**: A generic interface
|
|
47
|
-
- **
|
|
46
|
+
- **Tool**: A generic interface parameterized by `<Args, ReturnType, ContextType>` that binds parameter argument types and handler execution to strict contracts. `ContextType` defaults to `BaseToolCapability`, ensuring that each tool explicitly requests only the dependencies it requires.
|
|
47
|
+
- **Capability Contexts**: Instead of passing a monolithic grab-bag context to all tools, dependencies are broken into narrow capability interfaces (e.g. `PageExecutionCapability`, `StyleMutationCapability`, `TargetCapability`, `OriginLockCapability`). Tools declare their required dependencies by intersecting these interfaces on their generic `ContextType` definition. The caller/Agent fulfills the complete capability context (`AllToolsContext`), guaranteeing 100% compile-time type safety for dependencies without runtime checks.
|
|
48
|
+
- **ToolRegistry**: A static registry (`ToolRegistry`) storing instantiated tools. It uses TypeScript function overloading and generic lookups (`static get<K extends keyof typeof TOOLS>(name: K): typeof TOOLS[K]`) to return the precise class type of each tool, preventing type-erasure and escape-hatches (such as `any` or `as unknown` type assertions) at integration points like `AiAgent2.ts`. See the [Tools README](tools/README.md) for authoring instructions.
|
|
48
49
|
|
|
49
50
|
## Performance specific documentation
|
|
50
51
|
|
|
@@ -13,6 +13,8 @@ import {ChangeManager} from '../ChangeManager.js';
|
|
|
13
13
|
import {LighthouseFormatter} from '../data_formatters/LighthouseFormatter.js';
|
|
14
14
|
import {debugLog} from '../debug.js';
|
|
15
15
|
import {ExtensionScope} from '../ExtensionScope.js';
|
|
16
|
+
import {ToolName} from '../tools/Tool.js';
|
|
17
|
+
import {ToolRegistry} from '../tools/ToolRegistry.js';
|
|
16
18
|
|
|
17
19
|
import {
|
|
18
20
|
AiAgent,
|
|
@@ -25,10 +27,8 @@ import {
|
|
|
25
27
|
} from './AiAgent.js';
|
|
26
28
|
import {
|
|
27
29
|
type CreateExtensionScopeFunction,
|
|
28
|
-
executeJavaScriptFunction,
|
|
29
30
|
type ExecuteJsAgentOptions,
|
|
30
31
|
executeJsCode,
|
|
31
|
-
JavascriptExecutor
|
|
32
32
|
} from './ExecuteJavascript.js';
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -117,7 +117,6 @@ export class AccessibilityAgent extends AiAgent<LHModel.ReporterTypes.ReportJSON
|
|
|
117
117
|
(overrides?: LHModel.RunTypes.RunOverrides) => Promise<LHModel.ReporterTypes.ReportJSON|null>;
|
|
118
118
|
|
|
119
119
|
#execJs: typeof executeJsCode;
|
|
120
|
-
#javascriptExecutor: JavascriptExecutor;
|
|
121
120
|
#changes: ChangeManager;
|
|
122
121
|
#createExtensionScope: CreateExtensionScopeFunction;
|
|
123
122
|
|
|
@@ -129,14 +128,6 @@ export class AccessibilityAgent extends AiAgent<LHModel.ReporterTypes.ReportJSON
|
|
|
129
128
|
this.#createExtensionScope = opts.createExtensionScope ?? ((changes: ChangeManager) => {
|
|
130
129
|
return new ExtensionScope(changes, this.sessionId, this.#getDocumentBodyNode());
|
|
131
130
|
});
|
|
132
|
-
this.#javascriptExecutor = new JavascriptExecutor(
|
|
133
|
-
{
|
|
134
|
-
executionMode: this.executionMode,
|
|
135
|
-
getContextNode: () => this.#getDocumentBodyNode(),
|
|
136
|
-
createExtensionScope: this.#createExtensionScope.bind(this),
|
|
137
|
-
changes: this.#changes,
|
|
138
|
-
},
|
|
139
|
-
this.#execJs);
|
|
140
131
|
}
|
|
141
132
|
|
|
142
133
|
get userTier(): string|undefined {
|
|
@@ -271,16 +262,31 @@ export class AccessibilityAgent extends AiAgent<LHModel.ReporterTypes.ReportJSON
|
|
|
271
262
|
}
|
|
272
263
|
});
|
|
273
264
|
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
265
|
+
const executeJsTool = ToolRegistry.get(ToolName.EXECUTE_JAVASCRIPT);
|
|
266
|
+
if (!executeJsTool) {
|
|
267
|
+
throw new Error('Required tool "executeJavaScript" not found');
|
|
268
|
+
}
|
|
269
|
+
this.declareFunction(executeJsTool.name, {
|
|
270
|
+
description: executeJsTool.description,
|
|
271
|
+
parameters: executeJsTool.parameters,
|
|
272
|
+
displayInfoFromArgs: executeJsTool.displayInfoFromArgs,
|
|
273
|
+
handler: async (args, options) => {
|
|
278
274
|
if (isImported) {
|
|
279
275
|
return {
|
|
280
276
|
error: 'Cannot use this tool on an imported file.',
|
|
281
277
|
};
|
|
282
278
|
}
|
|
283
|
-
return await
|
|
279
|
+
return await executeJsTool.handler(
|
|
280
|
+
args,
|
|
281
|
+
{
|
|
282
|
+
conversationContext: this.context ?? null,
|
|
283
|
+
changeManager: this.#changes,
|
|
284
|
+
createExtensionScope: this.#createExtensionScope.bind(this),
|
|
285
|
+
execJs: this.#execJs,
|
|
286
|
+
getExecutionContextNode: () => this.#getDocumentBodyNode(),
|
|
287
|
+
},
|
|
288
|
+
options,
|
|
289
|
+
);
|
|
284
290
|
},
|
|
285
291
|
});
|
|
286
292
|
|