chrome-devtools-frontend 1.0.1642845 → 1.0.1643099
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/SECURITY.md +1 -0
- package/front_end/core/host/UserMetrics.ts +2 -1
- package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
- package/front_end/core/sdk/CSSMatchedStyles.ts +55 -26
- package/front_end/core/sdk/CSSRule.ts +1 -0
- package/front_end/core/sdk/DebuggerModel.ts +5 -0
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +4 -3
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +4 -3
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +4 -5
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/protocol.ts +7 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +100 -18
- package/front_end/models/ai_assistance/AiConversation.ts +18 -14
- package/front_end/models/ai_assistance/AiUtils.ts +71 -0
- package/front_end/models/ai_assistance/ChangeManager.ts +2 -5
- package/front_end/models/ai_assistance/{agents/ConversationSummaryAgent.ts → ConversationSummary.ts} +29 -66
- package/front_end/models/ai_assistance/ExtensionScope.ts +1 -4
- package/front_end/models/ai_assistance/{agents/PerformanceAnnotationsAgent.ts → PerformanceAnnotations.ts} +47 -89
- package/front_end/models/ai_assistance/README.md +8 -0
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +65 -40
- package/front_end/models/ai_assistance/agents/AiAgent.ts +37 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +11 -0
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +55 -5
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +2 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +119 -78
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +47 -38
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -25
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +46 -326
- package/front_end/models/ai_assistance/ai_assistance.ts +14 -4
- package/front_end/models/ai_assistance/contexts/DOMNodeContext.snapshot.txt +51 -0
- package/front_end/models/ai_assistance/contexts/DOMNodeContext.ts +200 -0
- package/front_end/models/ai_assistance/skills/styling.md +44 -2
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +140 -0
- package/front_end/models/ai_assistance/tools/GetStyles.ts +141 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +64 -0
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +36 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +5 -7
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +5 -0
- package/front_end/models/live-metrics/LiveMetrics.ts +24 -13
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +2 -2
- package/front_end/models/stack_trace/StackTrace.ts +4 -1
- package/front_end/models/stack_trace/StackTraceImpl.ts +9 -2
- package/front_end/models/stack_trace/StackTraceModel.ts +17 -4
- package/front_end/models/stack_trace/Trie.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +25 -22
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +16 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +96 -4
- package/front_end/panels/ai_assistance/components/chatMessage.css +6 -0
- package/front_end/panels/application/DOMStorageItemsView.ts +4 -0
- package/front_end/panels/application/KeyValueStorageItemsView.ts +39 -7
- package/front_end/panels/application/components/AdsView.ts +219 -0
- package/front_end/panels/application/components/adsView.css +54 -0
- package/front_end/panels/application/components/components.ts +2 -0
- package/front_end/panels/common/ExtensionServer.ts +26 -15
- package/front_end/panels/console/SymbolizedErrorWidget.ts +73 -22
- package/front_end/panels/elements/StandaloneStylesContainer.ts +1 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +8 -0
- package/front_end/panels/elements/StylePropertyHighlighter.ts +4 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -5
- package/front_end/panels/elements/StylesContainer.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +4 -4
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +106 -132
- package/front_end/panels/lighthouse/LighthousePanel.ts +4 -3
- package/front_end/panels/network/NetworkLogView.ts +8 -1
- package/front_end/panels/network/networkLogView.css +0 -15
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +5 -4
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1607 -5733
- package/front_end/third_party/lighthouse/locales/ar-XB.json +290 -65
- package/front_end/third_party/lighthouse/locales/ar.json +290 -65
- package/front_end/third_party/lighthouse/locales/bg.json +290 -65
- package/front_end/third_party/lighthouse/locales/ca.json +295 -70
- package/front_end/third_party/lighthouse/locales/cs.json +290 -65
- package/front_end/third_party/lighthouse/locales/da.json +294 -69
- package/front_end/third_party/lighthouse/locales/de.json +295 -70
- package/front_end/third_party/lighthouse/locales/el.json +290 -65
- package/front_end/third_party/lighthouse/locales/en-GB.json +290 -65
- package/front_end/third_party/lighthouse/locales/en-US.json +79 -67
- package/front_end/third_party/lighthouse/locales/en-XA.json +253 -64
- package/front_end/third_party/lighthouse/locales/en-XL.json +79 -67
- package/front_end/third_party/lighthouse/locales/es-419.json +290 -65
- package/front_end/third_party/lighthouse/locales/es.json +298 -73
- package/front_end/third_party/lighthouse/locales/fi.json +290 -65
- package/front_end/third_party/lighthouse/locales/fil.json +290 -65
- package/front_end/third_party/lighthouse/locales/fr.json +294 -69
- package/front_end/third_party/lighthouse/locales/he.json +293 -68
- package/front_end/third_party/lighthouse/locales/hi.json +291 -66
- package/front_end/third_party/lighthouse/locales/hr.json +290 -65
- package/front_end/third_party/lighthouse/locales/hu.json +290 -65
- package/front_end/third_party/lighthouse/locales/id.json +290 -65
- package/front_end/third_party/lighthouse/locales/it.json +294 -69
- package/front_end/third_party/lighthouse/locales/ja.json +290 -65
- package/front_end/third_party/lighthouse/locales/ko.json +290 -65
- package/front_end/third_party/lighthouse/locales/lt.json +290 -65
- package/front_end/third_party/lighthouse/locales/lv.json +290 -65
- package/front_end/third_party/lighthouse/locales/nl.json +290 -65
- package/front_end/third_party/lighthouse/locales/no.json +290 -65
- package/front_end/third_party/lighthouse/locales/pl.json +290 -65
- package/front_end/third_party/lighthouse/locales/pt-PT.json +291 -66
- package/front_end/third_party/lighthouse/locales/pt.json +290 -65
- package/front_end/third_party/lighthouse/locales/ro.json +290 -65
- package/front_end/third_party/lighthouse/locales/ru.json +301 -76
- package/front_end/third_party/lighthouse/locales/sk.json +291 -66
- package/front_end/third_party/lighthouse/locales/sl.json +290 -65
- package/front_end/third_party/lighthouse/locales/sr-Latn.json +290 -65
- package/front_end/third_party/lighthouse/locales/sr.json +290 -65
- package/front_end/third_party/lighthouse/locales/sv.json +297 -72
- package/front_end/third_party/lighthouse/locales/ta.json +291 -66
- package/front_end/third_party/lighthouse/locales/te.json +293 -68
- package/front_end/third_party/lighthouse/locales/th.json +291 -66
- package/front_end/third_party/lighthouse/locales/tr.json +290 -65
- package/front_end/third_party/lighthouse/locales/uk.json +290 -65
- package/front_end/third_party/lighthouse/locales/vi.json +291 -66
- package/front_end/third_party/lighthouse/locales/zh-HK.json +292 -67
- package/front_end/third_party/lighthouse/locales/zh-TW.json +291 -66
- package/front_end/third_party/lighthouse/locales/zh.json +291 -66
- package/front_end/third_party/lighthouse/report/bundle.d.ts +6 -6
- package/front_end/third_party/lighthouse/report/bundle.js +4 -7
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/ui/legacy/Widget.ts +32 -8
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +36 -3
- package/front_end/ui/legacy/components/data_grid/dataGridAiButton.css +20 -0
- package/front_end/ui/legacy/components/utils/Linkifier.ts +19 -4
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Host from '../../../core/host/host.js';
|
|
6
|
-
import * as i18n from '../../../core/i18n/i18n.js';
|
|
7
6
|
import * as Root from '../../../core/root/root.js';
|
|
8
7
|
import * as SDK from '../../../core/sdk/sdk.js';
|
|
9
8
|
import * as Protocol from '../../../generated/protocol.js';
|
|
@@ -11,16 +10,15 @@ import * as Greendev from '../../../models/greendev/greendev.js';
|
|
|
11
10
|
import * as Annotations from '../../annotations/annotations.js';
|
|
12
11
|
import * as Emulation from '../../emulation/emulation.js';
|
|
13
12
|
import {ChangeManager} from '../ChangeManager.js';
|
|
14
|
-
import {debugLog} from '../debug.js';
|
|
15
13
|
import {ExtensionScope} from '../ExtensionScope.js';
|
|
16
14
|
import {AI_ASSISTANCE_CSS_CLASS_NAME} from '../injected.js';
|
|
15
|
+
import {ToolName} from '../tools/Tool.js';
|
|
16
|
+
import {ToolRegistry} from '../tools/ToolRegistry.js';
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
19
|
AiAgent,
|
|
20
|
-
type ComputedStyleAiWidget,
|
|
21
20
|
type ContextResponse,
|
|
22
|
-
ConversationContext,
|
|
23
|
-
type ConversationSuggestions,
|
|
21
|
+
type ConversationContext,
|
|
24
22
|
type FunctionCallHandlerResult,
|
|
25
23
|
type MultimodalInput,
|
|
26
24
|
MultimodalInputType,
|
|
@@ -29,24 +27,10 @@ import {
|
|
|
29
27
|
} from './AiAgent.js';
|
|
30
28
|
import {
|
|
31
29
|
type CreateExtensionScopeFunction,
|
|
32
|
-
executeJavaScriptFunction,
|
|
33
30
|
type ExecuteJsAgentOptions,
|
|
34
31
|
executeJsCode,
|
|
35
|
-
JavascriptExecutor
|
|
36
32
|
} from './ExecuteJavascript.js';
|
|
37
33
|
|
|
38
|
-
/*
|
|
39
|
-
* Strings that don't need to be translated at this time.
|
|
40
|
-
*/
|
|
41
|
-
const UIStringsNotTranslate = {
|
|
42
|
-
/**
|
|
43
|
-
* @description Heading text for context details of Freestyler agent.
|
|
44
|
-
*/
|
|
45
|
-
dataUsed: 'Data used',
|
|
46
|
-
} as const;
|
|
47
|
-
|
|
48
|
-
const lockedString = i18n.i18n.lockedString;
|
|
49
|
-
|
|
50
34
|
const preamble = `You are the most advanced CSS/DOM/HTML debugging assistant integrated into Chrome DevTools.
|
|
51
35
|
You always suggest considering the best web development practices and the newest platform features such as view transitions.
|
|
52
36
|
The user selected a DOM element in the browser's DevTools and sends a query about the page or the selected DOM element.
|
|
@@ -152,78 +136,6 @@ const MULTIMODAL_ENHANCEMENT_PROMPTS: Record<MultimodalInputType, string> = {
|
|
|
152
136
|
|
|
153
137
|
export const AI_ASSISTANCE_FILTER_REGEX = `\\.${AI_ASSISTANCE_CSS_CLASS_NAME}-.*&`;
|
|
154
138
|
|
|
155
|
-
export class NodeContext extends ConversationContext<SDK.DOMModel.DOMNode> {
|
|
156
|
-
#node: SDK.DOMModel.DOMNode;
|
|
157
|
-
|
|
158
|
-
constructor(node: SDK.DOMModel.DOMNode) {
|
|
159
|
-
super();
|
|
160
|
-
this.#node = node;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
override getURL(): string {
|
|
164
|
-
const ownerDocument = this.#node.ownerDocument;
|
|
165
|
-
if (!ownerDocument) {
|
|
166
|
-
// The node is detached from a document.
|
|
167
|
-
return 'detached';
|
|
168
|
-
}
|
|
169
|
-
return ownerDocument.documentURL;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
getItem(): SDK.DOMModel.DOMNode {
|
|
173
|
-
return this.#node;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
override getTitle(): string {
|
|
177
|
-
throw new Error('Not implemented');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
override async getSuggestions(): Promise<ConversationSuggestions|undefined> {
|
|
181
|
-
const layoutProps = await this.#node.domModel().cssModel().getLayoutPropertiesFromComputedStyle(this.#node.id);
|
|
182
|
-
|
|
183
|
-
if (!layoutProps) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (layoutProps.isFlex) {
|
|
188
|
-
return [
|
|
189
|
-
{title: 'How can I make flex items wrap?', jslogContext: 'flex-wrap'},
|
|
190
|
-
{title: 'How do I distribute flex items evenly?', jslogContext: 'flex-distribute'},
|
|
191
|
-
{title: 'What is flexbox?', jslogContext: 'flex-what'},
|
|
192
|
-
];
|
|
193
|
-
}
|
|
194
|
-
if (layoutProps.isSubgrid) {
|
|
195
|
-
return [
|
|
196
|
-
{title: 'Where is this grid defined?', jslogContext: 'subgrid-where'},
|
|
197
|
-
{title: 'How to overwrite parent grid properties?', jslogContext: 'subgrid-override'},
|
|
198
|
-
{title: 'How do subgrids work? ', jslogContext: 'subgrid-how'},
|
|
199
|
-
];
|
|
200
|
-
}
|
|
201
|
-
if (layoutProps.isGrid) {
|
|
202
|
-
return [
|
|
203
|
-
{title: 'How do I align items in a grid?', jslogContext: 'grid-align'},
|
|
204
|
-
{title: 'How to add spacing between grid items?', jslogContext: 'grid-gap'},
|
|
205
|
-
{title: 'How does grid layout work?', jslogContext: 'grid-how'},
|
|
206
|
-
];
|
|
207
|
-
}
|
|
208
|
-
if (layoutProps.hasScroll) {
|
|
209
|
-
return [
|
|
210
|
-
{title: 'How do I remove scrollbars for this element?', jslogContext: 'scroll-remove'},
|
|
211
|
-
{title: 'How can I style a scrollbar?', jslogContext: 'scroll-style'},
|
|
212
|
-
{title: 'Why does this element scroll?', jslogContext: 'scroll-why'},
|
|
213
|
-
];
|
|
214
|
-
}
|
|
215
|
-
if (layoutProps.containerType) {
|
|
216
|
-
return [
|
|
217
|
-
{title: 'What are container queries?', jslogContext: 'container-what'},
|
|
218
|
-
{title: 'How do I use container-type?', jslogContext: 'container-how'},
|
|
219
|
-
{title: 'What\'s the container context for this element?', jslogContext: 'container-context'},
|
|
220
|
-
];
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
139
|
/**
|
|
228
140
|
* One agent instance handles one conversation. Create a new agent
|
|
229
141
|
* instance for a new conversation.
|
|
@@ -255,88 +167,55 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
|
|
|
255
167
|
}
|
|
256
168
|
|
|
257
169
|
#execJs: typeof executeJsCode;
|
|
258
|
-
#javascriptExecutor: JavascriptExecutor;
|
|
259
170
|
|
|
260
171
|
#changes: ChangeManager;
|
|
261
172
|
#createExtensionScope: CreateExtensionScopeFunction;
|
|
262
173
|
#greenDevEmulationScreenshot: string|null = null;
|
|
263
174
|
#greenDevEmulationAxTree: string|null = null;
|
|
264
175
|
#hasAddedEmulationInstructions = false;
|
|
265
|
-
#currentTurnId = 0;
|
|
266
176
|
|
|
267
177
|
constructor(opts: ExecuteJsAgentOptions) {
|
|
268
178
|
super(opts);
|
|
269
179
|
|
|
270
180
|
this.#changes = opts.changeManager || new ChangeManager();
|
|
271
181
|
this.#execJs = opts.execJs ?? executeJsCode;
|
|
272
|
-
this.#createExtensionScope =
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
explanation: string,
|
|
289
|
-
}>('getStyles', {
|
|
290
|
-
description:
|
|
291
|
-
`Get computed and source styles for one or multiple elements on the inspected page for multiple elements at once by uid.
|
|
182
|
+
this.#createExtensionScope = opts.createExtensionScope ?? ((changes: ChangeManager) => {
|
|
183
|
+
return new ExtensionScope(changes, this.sessionId, this.context?.getItem() ?? null);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const getStylesTool = ToolRegistry.get(ToolName.GET_STYLES);
|
|
187
|
+
if (!getStylesTool) {
|
|
188
|
+
throw new Error('Required tool "getStyles" not found');
|
|
189
|
+
}
|
|
190
|
+
this.declareFunction(ToolName.GET_STYLES, {
|
|
191
|
+
description: getStylesTool.description,
|
|
192
|
+
parameters: getStylesTool.parameters,
|
|
193
|
+
displayInfoFromArgs: getStylesTool.displayInfoFromArgs,
|
|
194
|
+
handler: args => getStylesTool.handler(args, {
|
|
195
|
+
conversationContext: this.context ?? null,
|
|
196
|
+
}),
|
|
197
|
+
});
|
|
292
198
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
type: Host.AidaClient.ParametersTypes.ARRAY,
|
|
309
|
-
description: 'A list of element uids to get data for. These are numbers, not selectors.',
|
|
310
|
-
items: {type: Host.AidaClient.ParametersTypes.INTEGER, description: `An element uid.`},
|
|
311
|
-
nullable: false,
|
|
199
|
+
const executeJsTool = ToolRegistry.get(ToolName.EXECUTE_JAVASCRIPT);
|
|
200
|
+
if (!executeJsTool) {
|
|
201
|
+
throw new Error('Required tool "executeJavaScript" not found');
|
|
202
|
+
}
|
|
203
|
+
this.declareFunction(ToolName.EXECUTE_JAVASCRIPT, {
|
|
204
|
+
description: executeJsTool.description,
|
|
205
|
+
parameters: executeJsTool.parameters,
|
|
206
|
+
displayInfoFromArgs: executeJsTool.displayInfoFromArgs,
|
|
207
|
+
handler: (args, options) => executeJsTool.handler(
|
|
208
|
+
args,
|
|
209
|
+
{
|
|
210
|
+
conversationContext: this.context ?? null,
|
|
211
|
+
changeManager: this.#changes,
|
|
212
|
+
createExtensionScope: this.#createExtensionScope.bind(this),
|
|
213
|
+
execJs: this.#execJs,
|
|
312
214
|
},
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
description:
|
|
316
|
-
'One or more specific CSS style property names to fetch. Generic values like "all" or "*" are not supported.',
|
|
317
|
-
nullable: false,
|
|
318
|
-
items: {
|
|
319
|
-
type: Host.AidaClient.ParametersTypes.STRING,
|
|
320
|
-
description: 'A CSS style property name to retrieve. For example, \'background-color\'.'
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
required: ['explanation', 'elements', 'styleProperties']
|
|
325
|
-
},
|
|
326
|
-
displayInfoFromArgs: params => {
|
|
327
|
-
return {
|
|
328
|
-
title: 'Reading computed and source styles',
|
|
329
|
-
thought: params.explanation,
|
|
330
|
-
action: `getStyles(${JSON.stringify(params.elements)}, ${JSON.stringify(params.styleProperties)})`,
|
|
331
|
-
};
|
|
332
|
-
},
|
|
333
|
-
handler: async params => {
|
|
334
|
-
return await this.#getStyles(params.elements, params.styleProperties);
|
|
335
|
-
},
|
|
215
|
+
options,
|
|
216
|
+
),
|
|
336
217
|
});
|
|
337
218
|
|
|
338
|
-
this.declareFunction('executeJavaScript', executeJavaScriptFunction(this.#javascriptExecutor));
|
|
339
|
-
|
|
340
219
|
if (Annotations.AnnotationRepository.annotationsEnabled()) {
|
|
341
220
|
this.declareFunction<{
|
|
342
221
|
elementId: string,
|
|
@@ -401,162 +280,10 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
|
|
|
401
280
|
});
|
|
402
281
|
}
|
|
403
282
|
|
|
404
|
-
static async describeElement(element: SDK.DOMModel.DOMNode): Promise<string> {
|
|
405
|
-
let output = `* Element's uid is ${element.backendNodeId()}.
|
|
406
|
-
* Its selector is \`${element.simpleSelector()}\``;
|
|
407
|
-
const childNodes = await element.getChildNodesPromise();
|
|
408
|
-
if (childNodes) {
|
|
409
|
-
const textChildNodes = childNodes.filter(childNode => childNode.nodeType() === Node.TEXT_NODE);
|
|
410
|
-
const elementChildNodes = childNodes.filter(childNode => childNode.nodeType() === Node.ELEMENT_NODE);
|
|
411
|
-
switch (elementChildNodes.length) {
|
|
412
|
-
case 0:
|
|
413
|
-
output += '\n* It doesn\'t have any child element nodes';
|
|
414
|
-
break;
|
|
415
|
-
case 1:
|
|
416
|
-
output += `\n* It only has 1 child element node: \`${elementChildNodes[0].simpleSelector()}\``;
|
|
417
|
-
break;
|
|
418
|
-
default:
|
|
419
|
-
output += `\n* It has ${elementChildNodes.length} child element nodes: ${
|
|
420
|
-
elementChildNodes.map(node => `\`${node.simpleSelector()}\` (uid=${node.backendNodeId()})`).join(', ')}`;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
switch (textChildNodes.length) {
|
|
424
|
-
case 0:
|
|
425
|
-
output += '\n* It doesn\'t have any child text nodes';
|
|
426
|
-
break;
|
|
427
|
-
case 1:
|
|
428
|
-
output += '\n* It only has 1 child text node';
|
|
429
|
-
break;
|
|
430
|
-
default:
|
|
431
|
-
output += `\n* It has ${textChildNodes.length} child text nodes`;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (element.nextSibling) {
|
|
436
|
-
const elementOrNodeElementNodeText = element.nextSibling.nodeType() === Node.ELEMENT_NODE ?
|
|
437
|
-
`an element (uid=${element.nextSibling.backendNodeId()})` :
|
|
438
|
-
'a non element';
|
|
439
|
-
output += `\n* It has a next sibling and it is ${elementOrNodeElementNodeText} node`;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
if (element.previousSibling) {
|
|
443
|
-
const elementOrNodeElementNodeText = element.previousSibling.nodeType() === Node.ELEMENT_NODE ?
|
|
444
|
-
`an element (uid=${element.previousSibling.backendNodeId()})` :
|
|
445
|
-
'a non element';
|
|
446
|
-
output += `\n* It has a previous sibling and it is ${elementOrNodeElementNodeText} node`;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
if (element.isInShadowTree()) {
|
|
450
|
-
output += '\n* It is in a shadow DOM tree.';
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const parentNode = element.parentNode;
|
|
454
|
-
if (parentNode) {
|
|
455
|
-
const parentChildrenNodes = await parentNode.getChildNodesPromise();
|
|
456
|
-
output += `\n* Its parent's selector is \`${parentNode.simpleSelector()}\` (uid=${parentNode.backendNodeId()})`;
|
|
457
|
-
const elementOrNodeElementNodeText = parentNode.nodeType() === Node.ELEMENT_NODE ? 'an element' : 'a non element';
|
|
458
|
-
output += `\n* Its parent is ${elementOrNodeElementNodeText} node`;
|
|
459
|
-
if (parentNode.isShadowRoot()) {
|
|
460
|
-
output += '\n* Its parent is a shadow root.';
|
|
461
|
-
}
|
|
462
|
-
if (parentChildrenNodes) {
|
|
463
|
-
const childElementNodes =
|
|
464
|
-
parentChildrenNodes.filter(siblingNode => siblingNode.nodeType() === Node.ELEMENT_NODE);
|
|
465
|
-
switch (childElementNodes.length) {
|
|
466
|
-
case 0:
|
|
467
|
-
break;
|
|
468
|
-
case 1:
|
|
469
|
-
output += '\n* Its parent has only 1 child element node';
|
|
470
|
-
break;
|
|
471
|
-
default:
|
|
472
|
-
output += `\n* Its parent has ${childElementNodes.length} child element nodes: ${
|
|
473
|
-
childElementNodes.map(node => `\`${node.simpleSelector()}\` (uid=${node.backendNodeId()})`)
|
|
474
|
-
.join(', ')}`;
|
|
475
|
-
break;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const siblingTextNodes = parentChildrenNodes.filter(siblingNode => siblingNode.nodeType() === Node.TEXT_NODE);
|
|
479
|
-
switch (siblingTextNodes.length) {
|
|
480
|
-
case 0:
|
|
481
|
-
break;
|
|
482
|
-
case 1:
|
|
483
|
-
output += '\n* Its parent has only 1 child text node';
|
|
484
|
-
break;
|
|
485
|
-
default:
|
|
486
|
-
output += `\n* Its parent has ${siblingTextNodes.length} child text nodes: ${
|
|
487
|
-
siblingTextNodes.map(node => `\`${node.simpleSelector()}\``).join(', ')}`;
|
|
488
|
-
break;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
return output.trim();
|
|
494
|
-
}
|
|
495
|
-
|
|
496
283
|
#getSelectedNode(): SDK.DOMModel.DOMNode|null {
|
|
497
284
|
return this.context?.getItem() ?? null;
|
|
498
285
|
}
|
|
499
286
|
|
|
500
|
-
async #getStyles(elements: number[], properties: string[]): Promise<FunctionCallHandlerResult<unknown>> {
|
|
501
|
-
const widgets: ComputedStyleAiWidget[] = [];
|
|
502
|
-
|
|
503
|
-
const result:
|
|
504
|
-
Record<string, {computed: Record<string, string|undefined>, authored: Record<string, string|undefined>}> = {};
|
|
505
|
-
for (const uid of elements) {
|
|
506
|
-
result[uid] = {computed: {}, authored: {}};
|
|
507
|
-
debugLog(`Action to execute: uid=${uid}`);
|
|
508
|
-
const selectedNode = this.#getSelectedNode();
|
|
509
|
-
if (!selectedNode) {
|
|
510
|
-
return {error: 'Error: Could not find the currently selected element.'};
|
|
511
|
-
}
|
|
512
|
-
const node = new SDK.DOMModel.DeferredDOMNode(
|
|
513
|
-
selectedNode.domModel().target(), Number(uid) as unknown as Protocol.DOM.BackendNodeId);
|
|
514
|
-
const resolved = await node.resolvePromise();
|
|
515
|
-
if (!resolved) {
|
|
516
|
-
return {error: 'Error: Could not find the element with uid=' + uid};
|
|
517
|
-
}
|
|
518
|
-
const newContext = new NodeContext(resolved);
|
|
519
|
-
if (this.context?.getOrigin() !== newContext.getOrigin()) {
|
|
520
|
-
return {error: 'Error: Node does not belong to the current origin.'};
|
|
521
|
-
}
|
|
522
|
-
const styles = await resolved.domModel().cssModel().getComputedStyle(resolved.id);
|
|
523
|
-
if (!styles) {
|
|
524
|
-
return {error: 'Error: Could not get computed styles.'};
|
|
525
|
-
}
|
|
526
|
-
const matchedStyles = await resolved.domModel().cssModel().getMatchedStyles(resolved.id);
|
|
527
|
-
if (!matchedStyles) {
|
|
528
|
-
return {error: 'Error: Could not get authored styles.'};
|
|
529
|
-
}
|
|
530
|
-
widgets.push({
|
|
531
|
-
name: 'COMPUTED_STYLES',
|
|
532
|
-
data: {
|
|
533
|
-
computedStyles: styles,
|
|
534
|
-
backendNodeId: node.backendNodeId(),
|
|
535
|
-
matchedCascade: matchedStyles,
|
|
536
|
-
properties,
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
for (const prop of properties) {
|
|
540
|
-
result[uid].computed[prop] = styles.get(prop);
|
|
541
|
-
}
|
|
542
|
-
for (const style of matchedStyles.nodeStyles()) {
|
|
543
|
-
for (const property of style.allProperties()) {
|
|
544
|
-
if (!properties.includes(property.name)) {
|
|
545
|
-
continue;
|
|
546
|
-
}
|
|
547
|
-
const state = matchedStyles.propertyState(property);
|
|
548
|
-
if (state === SDK.CSSMatchedStyles.PropertyState.ACTIVE) {
|
|
549
|
-
result[uid].authored[property.name] = property.value;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
return {
|
|
555
|
-
result: JSON.stringify(result, null, 2),
|
|
556
|
-
widgets,
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
|
|
560
287
|
async addElementAnnotation(elementId: string, annotationMessage: string):
|
|
561
288
|
Promise<FunctionCallHandlerResult<unknown>> {
|
|
562
289
|
if (!Annotations.AnnotationRepository.annotationsEnabled()) {
|
|
@@ -782,20 +509,15 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
|
|
|
782
509
|
override async *
|
|
783
510
|
handleContextDetails(selectedElement: ConversationContext<SDK.DOMModel.DOMNode>|null):
|
|
784
511
|
AsyncGenerator<ContextResponse, void, void> {
|
|
785
|
-
if (
|
|
786
|
-
|
|
512
|
+
if (selectedElement) {
|
|
513
|
+
const details = await selectedElement.getUserFacingDetails();
|
|
514
|
+
if (details) {
|
|
515
|
+
yield {
|
|
516
|
+
type: ResponseType.CONTEXT,
|
|
517
|
+
details,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
787
520
|
}
|
|
788
|
-
yield {
|
|
789
|
-
type: ResponseType.CONTEXT,
|
|
790
|
-
details: [{
|
|
791
|
-
title: lockedString(UIStringsNotTranslate.dataUsed),
|
|
792
|
-
text: await StylingAgent.describeElement(selectedElement.getItem()),
|
|
793
|
-
}],
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
protected override async preRun(): Promise<void> {
|
|
798
|
-
this.#currentTurnId++;
|
|
799
521
|
}
|
|
800
522
|
|
|
801
523
|
override async enhanceQuery(
|
|
@@ -814,10 +536,8 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
|
|
|
814
536
|
this.#hasAddedEmulationInstructions = true;
|
|
815
537
|
}
|
|
816
538
|
|
|
817
|
-
const
|
|
818
|
-
|
|
819
|
-
await StylingAgent.describeElement(selectedElement.getItem())}\n\n# User request\n\n` :
|
|
820
|
-
'';
|
|
539
|
+
const promptDetails = selectedElement ? await selectedElement.getPromptDetails() : null;
|
|
540
|
+
const elementEnchancementQuery = promptDetails ? `${promptDetails}\n\n# User request\n\n` : '';
|
|
821
541
|
return `${multimodalInputEnhancementQuery}${elementEnchancementQuery}QUERY: ${query}`;
|
|
822
542
|
}
|
|
823
543
|
}
|
|
@@ -6,7 +6,6 @@ import * as AgentProject from './AgentProject.js';
|
|
|
6
6
|
import * as AccessibilityAgent from './agents/AccessibilityAgent.js';
|
|
7
7
|
import * as AiAgent from './agents/AiAgent.js';
|
|
8
8
|
import * as ContextSelectionAgent from './agents/ContextSelectionAgent.js';
|
|
9
|
-
import * as ConversationSummaryAgent from './agents/ConversationSummaryAgent.js';
|
|
10
9
|
import * as FileAgent from './agents/FileAgent.js';
|
|
11
10
|
import * as GreenDevAgent from './agents/GreenDevAgent.js';
|
|
12
11
|
import * as GreenDevAgentAntigravityCliSocketClient from './agents/GreenDevAgentAntigravityCliSocketClient.js';
|
|
@@ -14,7 +13,6 @@ import * as GreenDevAgentGeminiCliSocketClient from './agents/GreenDevAgentGemin
|
|
|
14
13
|
import * as NetworkAgent from './agents/NetworkAgent.js';
|
|
15
14
|
import * as PatchAgent from './agents/PatchAgent.js';
|
|
16
15
|
import * as PerformanceAgent from './agents/PerformanceAgent.js';
|
|
17
|
-
import * as PerformanceAnnotationsAgent from './agents/PerformanceAnnotationsAgent.js';
|
|
18
16
|
import * as StorageAgent from './agents/StorageAgent.js';
|
|
19
17
|
import * as StylingAgent from './agents/StylingAgent.js';
|
|
20
18
|
import * as AiAgent2 from './AiAgent2.js';
|
|
@@ -24,6 +22,8 @@ import * as AiOrigins from './AiOrigins.js';
|
|
|
24
22
|
import * as AiUtils from './AiUtils.js';
|
|
25
23
|
import * as BuiltInAi from './BuiltInAi.js';
|
|
26
24
|
import * as ChangeManager from './ChangeManager.js';
|
|
25
|
+
import * as DOMNodeContext from './contexts/DOMNodeContext.js';
|
|
26
|
+
import * as ConversationSummary from './ConversationSummary.js';
|
|
27
27
|
import * as FileFormatter from './data_formatters/FileFormatter.js';
|
|
28
28
|
import * as LighthouseFormatter from './data_formatters/LighthouseFormatter.js';
|
|
29
29
|
import * as NetworkRequestFormatter from './data_formatters/NetworkRequestFormatter.js';
|
|
@@ -37,7 +37,12 @@ import * as Injected from './injected.js';
|
|
|
37
37
|
import * as AICallTree from './performance/AICallTree.js';
|
|
38
38
|
import * as AIContext from './performance/AIContext.js';
|
|
39
39
|
import * as AIQueries from './performance/AIQueries.js';
|
|
40
|
+
import * as PerformanceAnnotations from './PerformanceAnnotations.js';
|
|
40
41
|
import * as StorageItem from './StorageItem.js';
|
|
42
|
+
import * as ExecuteJavaScript from './tools/ExecuteJavaScript.js';
|
|
43
|
+
import * as GetStyles from './tools/GetStyles.js';
|
|
44
|
+
import * as Tool from './tools/Tool.js';
|
|
45
|
+
import * as ToolRegistry from './tools/ToolRegistry.js';
|
|
41
46
|
|
|
42
47
|
export {
|
|
43
48
|
AccessibilityAgent,
|
|
@@ -54,12 +59,15 @@ export {
|
|
|
54
59
|
BuiltInAi,
|
|
55
60
|
ChangeManager,
|
|
56
61
|
ContextSelectionAgent,
|
|
57
|
-
|
|
62
|
+
ConversationSummary,
|
|
58
63
|
Debug,
|
|
64
|
+
DOMNodeContext,
|
|
59
65
|
EvaluateAction,
|
|
66
|
+
ExecuteJavaScript,
|
|
60
67
|
ExtensionScope,
|
|
61
68
|
FileAgent,
|
|
62
69
|
FileFormatter,
|
|
70
|
+
GetStyles,
|
|
63
71
|
GreenDevAgent,
|
|
64
72
|
GreenDevAgentAntigravityCliSocketClient,
|
|
65
73
|
GreenDevAgentGeminiCliSocketClient,
|
|
@@ -69,11 +77,13 @@ export {
|
|
|
69
77
|
NetworkRequestFormatter,
|
|
70
78
|
PatchAgent,
|
|
71
79
|
PerformanceAgent,
|
|
72
|
-
|
|
80
|
+
PerformanceAnnotations,
|
|
73
81
|
PerformanceInsightFormatter,
|
|
74
82
|
PerformanceTraceFormatter,
|
|
75
83
|
StorageAgent,
|
|
76
84
|
StorageItem,
|
|
77
85
|
StylingAgent,
|
|
86
|
+
Tool,
|
|
87
|
+
ToolRegistry,
|
|
78
88
|
UnitFormatters,
|
|
79
89
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Title: DOMNodeContext getPromptDetails describes the node correctly
|
|
2
|
+
Content:
|
|
3
|
+
# Inspected element
|
|
4
|
+
|
|
5
|
+
* Element's uid is 99.
|
|
6
|
+
* Its selector is `div#myElement`
|
|
7
|
+
=== end content
|
|
8
|
+
|
|
9
|
+
Title: DOMNodeContext getUserFacingDetails returns details with Data Used title
|
|
10
|
+
Content:
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"title": "Data used",
|
|
14
|
+
"text": "* Element's uid is 99.\n* Its selector is `div#myElement`"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
=== end content
|
|
18
|
+
|
|
19
|
+
Title: DOMNodeContext describes an element with child nodes not loaded
|
|
20
|
+
Content:
|
|
21
|
+
* Element's uid is 99.
|
|
22
|
+
* Its selector is `div#myElement`
|
|
23
|
+
=== end content
|
|
24
|
+
|
|
25
|
+
Title: DOMNodeContext describes an element with no children, siblings, or parent
|
|
26
|
+
Content:
|
|
27
|
+
* Element's uid is 99.
|
|
28
|
+
* Its selector is `div#myElement`
|
|
29
|
+
* It doesn't have any child element nodes
|
|
30
|
+
* It doesn't have any child text nodes
|
|
31
|
+
=== end content
|
|
32
|
+
|
|
33
|
+
Title: DOMNodeContext describes an element with child element and text nodes
|
|
34
|
+
Content:
|
|
35
|
+
* Element's uid is 99.
|
|
36
|
+
* Its selector is `div#parentElement`
|
|
37
|
+
* It has 2 child element nodes: `span.child1` (uid=undefined), `span.child2` (uid=undefined)
|
|
38
|
+
* It only has 1 child text node
|
|
39
|
+
=== end content
|
|
40
|
+
|
|
41
|
+
Title: DOMNodeContext describes an element with siblings and a parent
|
|
42
|
+
Content:
|
|
43
|
+
* Element's uid is 99.
|
|
44
|
+
* Its selector is `div#parentElement`
|
|
45
|
+
* It has a next sibling and it is an element (uid=undefined) node
|
|
46
|
+
* It has a previous sibling and it is a non element node
|
|
47
|
+
* Its parent's selector is `div#grandparentElement` (uid=undefined)
|
|
48
|
+
* Its parent is a non element node
|
|
49
|
+
* Its parent has only 1 child element node
|
|
50
|
+
* Its parent has only 1 child text node
|
|
51
|
+
=== end content
|