chrome-devtools-frontend 1.0.1642899 → 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/front_end/core/protocol_client/InspectorBackend.ts +4 -0
- 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 +23 -5
- package/front_end/models/ai_assistance/AiConversation.ts +15 -12
- 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/agents/AccessibilityAgent.ts +31 -21
- package/front_end/models/ai_assistance/agents/AiAgent.ts +21 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +11 -0
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +53 -3
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +2 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +72 -79
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +47 -38
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +22 -21
- package/front_end/models/ai_assistance/ai_assistance.ts +6 -4
- package/front_end/models/ai_assistance/skills/styling.md +12 -4
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +140 -0
- package/front_end/models/ai_assistance/tools/GetStyles.ts +6 -2
- package/front_end/models/ai_assistance/tools/Tool.ts +10 -1
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +2 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +5 -7
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +6 -7
- 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/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/console/SymbolizedErrorWidget.ts +73 -22
- package/front_end/panels/network/NetworkLogView.ts +5 -1
- 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/visual_logging/KnownContextValues.ts +2 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
|
@@ -339,6 +339,10 @@ export class TargetBase {
|
|
|
339
339
|
return this.getAgent('Autofill');
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
adsAgent(): ProtocolProxyApi.AdsApi {
|
|
343
|
+
return this.getAgent('Ads');
|
|
344
|
+
}
|
|
345
|
+
|
|
342
346
|
browserAgent(): ProtocolProxyApi.BrowserApi {
|
|
343
347
|
return this.getAgent('Browser');
|
|
344
348
|
}
|
|
@@ -876,7 +876,7 @@ export abstract class HeapSnapshot {
|
|
|
876
876
|
readonly #progress: HeapSnapshotProgress;
|
|
877
877
|
readonly #noDistance = -5;
|
|
878
878
|
rootNodeIndexInternal = 0;
|
|
879
|
-
#snapshotDiffs: Record<
|
|
879
|
+
#snapshotDiffs: Record<number, Record<string, HeapSnapshotModel.HeapSnapshotModel.Diff>> = {};
|
|
880
880
|
#aggregatesForDiff?: {
|
|
881
881
|
interfaceDefinitions: string,
|
|
882
882
|
aggregates: Record<string, HeapSnapshotModel.HeapSnapshotModel.AggregateForDiff>,
|
|
@@ -2688,9 +2688,8 @@ export abstract class HeapSnapshot {
|
|
|
2688
2688
|
throw new Error('Not implemented');
|
|
2689
2689
|
}
|
|
2690
2690
|
|
|
2691
|
-
calculateSnapshotDiff(
|
|
2692
|
-
|
|
2693
|
-
baseSnapshotAggregates: Record<string, HeapSnapshotModel.HeapSnapshotModel.AggregateForDiff>):
|
|
2691
|
+
calculateSnapshotDiff(baseSnapshotId: number,
|
|
2692
|
+
baseSnapshotAggregates: Record<string, HeapSnapshotModel.HeapSnapshotModel.AggregateForDiff>):
|
|
2694
2693
|
Record<string, HeapSnapshotModel.HeapSnapshotModel.Diff> {
|
|
2695
2694
|
let snapshotDiff: Record<string, HeapSnapshotModel.HeapSnapshotModel.Diff> = this.#snapshotDiffs[baseSnapshotId];
|
|
2696
2695
|
if (snapshotDiff) {
|
|
@@ -2976,7 +2975,7 @@ export abstract class HeapSnapshot {
|
|
|
2976
2975
|
return {paths, limitsReached};
|
|
2977
2976
|
}
|
|
2978
2977
|
|
|
2979
|
-
createAddedNodesProvider(baseSnapshotId:
|
|
2978
|
+
createAddedNodesProvider(baseSnapshotId: number, classKey: string): HeapSnapshotNodesProvider {
|
|
2980
2979
|
const snapshotDiff = this.#snapshotDiffs[baseSnapshotId];
|
|
2981
2980
|
const diffForClass = snapshotDiff[classKey];
|
|
2982
2981
|
return new HeapSnapshotNodesProvider(this, diffForClass.addedIndexes);
|
|
@@ -435,7 +435,7 @@ inspectorBackend.registerCommand("DOM.getFrameOwner", [{"name": "frameId", "type
|
|
|
435
435
|
inspectorBackend.registerCommand("DOM.getContainerForNode", [{"name": "nodeId", "type": "number", "optional": false, "description": "", "typeRef": "DOM.NodeId"}, {"name": "containerName", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "physicalAxes", "type": "string", "optional": true, "description": "", "typeRef": "DOM.PhysicalAxes"}, {"name": "logicalAxes", "type": "string", "optional": true, "description": "", "typeRef": "DOM.LogicalAxes"}, {"name": "queriesScrollState", "type": "boolean", "optional": true, "description": "", "typeRef": null}, {"name": "queriesAnchored", "type": "boolean", "optional": true, "description": "", "typeRef": null}], ["nodeId"], "Returns the query container of the given node based on container query conditions: containerName, physical and logical axes, and whether it queries scroll-state or anchored elements. If no axes are provided and queriesScrollState is false, the style container is returned, which is the direct parent or the closest element with a matching container-name.");
|
|
436
436
|
inspectorBackend.registerCommand("DOM.getQueryingDescendantsForContainer", [{"name": "nodeId", "type": "number", "optional": false, "description": "Id of the container node to find querying descendants from.", "typeRef": "DOM.NodeId"}], ["nodeIds"], "Returns the descendants of a container query container that have container queries against this container.");
|
|
437
437
|
inspectorBackend.registerCommand("DOM.getAnchorElement", [{"name": "nodeId", "type": "number", "optional": false, "description": "Id of the positioned element from which to find the anchor.", "typeRef": "DOM.NodeId"}, {"name": "anchorSpecifier", "type": "string", "optional": true, "description": "An optional anchor specifier, as defined in https://www.w3.org/TR/css-anchor-position-1/#anchor-specifier. If not provided, it will return the implicit anchor element for the given positioned element.", "typeRef": null}], ["nodeId"], "Returns the target anchor element of the given anchor query according to https://www.w3.org/TR/css-anchor-position-1/#target.");
|
|
438
|
-
inspectorBackend.registerCommand("DOM.forceShowPopover", [{"name": "nodeId", "type": "number", "optional": false, "description": "Id of the popover HTMLElement", "typeRef": "DOM.NodeId"}, {"name": "enable", "type": "boolean", "optional": false, "description": "If true, opens the popover and keeps it open. If false, closes the popover if it was previously force-opened.", "typeRef": null}], ["nodeIds"], "When enabling, this API force-opens the popover identified by nodeId and keeps it open until disabled.");
|
|
438
|
+
inspectorBackend.registerCommand("DOM.forceShowPopover", [{"name": "nodeId", "type": "number", "optional": false, "description": "Id of the popover HTMLElement", "typeRef": "DOM.NodeId"}, {"name": "enable", "type": "boolean", "optional": false, "description": "If true, opens the popover and keeps it open. If false, closes the popover if it was previously force-opened.", "typeRef": null}, {"name": "invokerNodeId", "type": "number", "optional": true, "description": "Optional ID of the element invoking this popover, used to establish the implicit anchor. If not provided, it will fall back to the first invoker in the document, preferring elements with a popovertarget attribute over those with a commandfor attribute. Note that if there are multiple invokers, this is just an estimate.", "typeRef": "DOM.BackendNodeId"}], ["nodeIds"], "When enabling, this API force-opens the popover identified by nodeId and keeps it open until disabled.");
|
|
439
439
|
inspectorBackend.registerType("DOM.BackendNode", [{"name": "nodeType", "type": "number", "optional": false, "description": "`Node`'s nodeType.", "typeRef": null}, {"name": "nodeName", "type": "string", "optional": false, "description": "`Node`'s nodeName.", "typeRef": null}, {"name": "backendNodeId", "type": "number", "optional": false, "description": "", "typeRef": "DOM.BackendNodeId"}]);
|
|
440
440
|
inspectorBackend.registerType("DOM.Node", [{"name": "nodeId", "type": "number", "optional": false, "description": "Node identifier that is passed into the rest of the DOM messages as the `nodeId`. Backend will only push node with given `id` once. It is aware of all requested nodes and will only fire DOM events for nodes known to the client.", "typeRef": "DOM.NodeId"}, {"name": "parentId", "type": "number", "optional": true, "description": "The id of the parent node if any.", "typeRef": "DOM.NodeId"}, {"name": "backendNodeId", "type": "number", "optional": false, "description": "The BackendNodeId for this node.", "typeRef": "DOM.BackendNodeId"}, {"name": "nodeType", "type": "number", "optional": false, "description": "`Node`'s nodeType.", "typeRef": null}, {"name": "nodeName", "type": "string", "optional": false, "description": "`Node`'s nodeName.", "typeRef": null}, {"name": "localName", "type": "string", "optional": false, "description": "`Node`'s localName.", "typeRef": null}, {"name": "nodeValue", "type": "string", "optional": false, "description": "`Node`'s nodeValue.", "typeRef": null}, {"name": "childNodeCount", "type": "number", "optional": true, "description": "Child count for `Container` nodes.", "typeRef": null}, {"name": "children", "type": "array", "optional": true, "description": "Child nodes of this node when requested with children.", "typeRef": "DOM.Node"}, {"name": "attributes", "type": "array", "optional": true, "description": "Attributes of the `Element` node in the form of flat array `[name1, value1, name2, value2]`.", "typeRef": "string"}, {"name": "documentURL", "type": "string", "optional": true, "description": "Document URL that `Document` or `FrameOwner` node points to.", "typeRef": null}, {"name": "baseURL", "type": "string", "optional": true, "description": "Base URL that `Document` or `FrameOwner` node uses for URL completion.", "typeRef": null}, {"name": "publicId", "type": "string", "optional": true, "description": "`DocumentType`'s publicId.", "typeRef": null}, {"name": "systemId", "type": "string", "optional": true, "description": "`DocumentType`'s systemId.", "typeRef": null}, {"name": "internalSubset", "type": "string", "optional": true, "description": "`DocumentType`'s internalSubset.", "typeRef": null}, {"name": "xmlVersion", "type": "string", "optional": true, "description": "`Document`'s XML version in case of XML documents.", "typeRef": null}, {"name": "name", "type": "string", "optional": true, "description": "`Attr`'s name.", "typeRef": null}, {"name": "value", "type": "string", "optional": true, "description": "`Attr`'s value.", "typeRef": null}, {"name": "pseudoType", "type": "string", "optional": true, "description": "Pseudo element type for this node.", "typeRef": "DOM.PseudoType"}, {"name": "pseudoIdentifier", "type": "string", "optional": true, "description": "Pseudo element identifier for this node. Only present if there is a valid pseudoType.", "typeRef": null}, {"name": "shadowRootType", "type": "string", "optional": true, "description": "Shadow root type.", "typeRef": "DOM.ShadowRootType"}, {"name": "frameId", "type": "string", "optional": true, "description": "Frame ID for frame owner elements.", "typeRef": "Page.FrameId"}, {"name": "contentDocument", "type": "object", "optional": true, "description": "Content document for frame owner elements.", "typeRef": "DOM.Node"}, {"name": "shadowRoots", "type": "array", "optional": true, "description": "Shadow root list for given element host.", "typeRef": "DOM.Node"}, {"name": "templateContent", "type": "object", "optional": true, "description": "Content document fragment for template elements.", "typeRef": "DOM.Node"}, {"name": "pseudoElements", "type": "array", "optional": true, "description": "Pseudo elements associated with this node.", "typeRef": "DOM.Node"}, {"name": "importedDocument", "type": "object", "optional": true, "description": "Deprecated, as the HTML Imports API has been removed (crbug.com/937746). This property used to return the imported document for the HTMLImport links. The property is always undefined now.", "typeRef": "DOM.Node"}, {"name": "distributedNodes", "type": "array", "optional": true, "description": "Distributed nodes for given insertion point.", "typeRef": "DOM.BackendNode"}, {"name": "isSVG", "type": "boolean", "optional": true, "description": "Whether the node is SVG.", "typeRef": null}, {"name": "compatibilityMode", "type": "string", "optional": true, "description": "", "typeRef": "DOM.CompatibilityMode"}, {"name": "assignedSlot", "type": "object", "optional": true, "description": "", "typeRef": "DOM.BackendNode"}, {"name": "isScrollable", "type": "boolean", "optional": true, "description": "", "typeRef": null}, {"name": "affectedByStartingStyles", "type": "boolean", "optional": true, "description": "", "typeRef": null}, {"name": "adoptedStyleSheets", "type": "array", "optional": true, "description": "", "typeRef": "DOM.StyleSheetId"}, {"name": "adProvenance", "type": "object", "optional": true, "description": "", "typeRef": "Network.AdProvenance"}]);
|
|
441
441
|
inspectorBackend.registerType("DOM.DetachedElementInfo", [{"name": "treeNode", "type": "object", "optional": false, "description": "", "typeRef": "DOM.Node"}, {"name": "retainedNodeIds", "type": "array", "optional": false, "description": "", "typeRef": "DOM.NodeId"}]);
|
|
@@ -5849,6 +5849,13 @@ export namespace DOM {
|
|
|
5849
5849
|
* popover if it was previously force-opened.
|
|
5850
5850
|
*/
|
|
5851
5851
|
enable: boolean;
|
|
5852
|
+
/**
|
|
5853
|
+
* Optional ID of the element invoking this popover, used to establish the implicit anchor.
|
|
5854
|
+
* If not provided, it will fall back to the first invoker in the document, preferring
|
|
5855
|
+
* elements with a popovertarget attribute over those with a commandfor attribute. Note that
|
|
5856
|
+
* if there are multiple invokers, this is just an estimate.
|
|
5857
|
+
*/
|
|
5858
|
+
invokerNodeId?: BackendNodeId;
|
|
5852
5859
|
}
|
|
5853
5860
|
|
|
5854
5861
|
export interface ForceShowPopoverResponse extends ProtocolResponseWithError {
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import * as Host from '../../core/host/host.js';
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
type AgentOptions,
|
|
9
8
|
AiAgent,
|
|
10
9
|
type ContextResponse,
|
|
11
10
|
type ConversationContext,
|
|
@@ -13,7 +12,11 @@ import {
|
|
|
13
12
|
type RequestOptions,
|
|
14
13
|
ResponseType
|
|
15
14
|
} from './agents/AiAgent.js';
|
|
15
|
+
import {type ExecuteJsAgentOptions, executeJsCode} from './agents/ExecuteJavascript.js';
|
|
16
|
+
import {ChangeManager} from './ChangeManager.js';
|
|
17
|
+
import {DOMNodeContext} from './contexts/DOMNodeContext.js';
|
|
16
18
|
import {debugLog} from './debug.js';
|
|
19
|
+
import {ExtensionScope} from './ExtensionScope.js';
|
|
17
20
|
import type {Skill, SkillName} from './skills/Skill.js';
|
|
18
21
|
import {SKILLS} from './skills/SkillRegistry.js';
|
|
19
22
|
import type {Tool} from './tools/Tool.js';
|
|
@@ -30,6 +33,8 @@ export class AiAgent2 extends AiAgent<unknown> {
|
|
|
30
33
|
readonly userTier = 'TESTERS';
|
|
31
34
|
|
|
32
35
|
#skillsInjected = false;
|
|
36
|
+
#changes = new ChangeManager();
|
|
37
|
+
#execJs: typeof executeJsCode;
|
|
33
38
|
|
|
34
39
|
get options(): RequestOptions {
|
|
35
40
|
return {};
|
|
@@ -38,8 +43,9 @@ export class AiAgent2 extends AiAgent<unknown> {
|
|
|
38
43
|
readonly #activeSkills = new Set<SkillName>();
|
|
39
44
|
readonly #declaredTools = new Set<string>();
|
|
40
45
|
|
|
41
|
-
constructor(opts:
|
|
46
|
+
constructor(opts: ExecuteJsAgentOptions) {
|
|
42
47
|
super(opts);
|
|
48
|
+
this.#execJs = opts.execJs ?? executeJsCode;
|
|
43
49
|
this.#declaredTools.add('learnSkills');
|
|
44
50
|
const skillsList = Object.keys(SKILLS).join(', ');
|
|
45
51
|
this.declareFunction<{skills: SkillName[]}>('learnSkills', {
|
|
@@ -154,6 +160,11 @@ User query: ${enhancedQuery}`;
|
|
|
154
160
|
return response.trim();
|
|
155
161
|
}
|
|
156
162
|
|
|
163
|
+
#createExtensionScope(changes: ChangeManager): {install(): Promise<void>, uninstall(): Promise<void>} {
|
|
164
|
+
const selectedNode = this.context && this.context instanceof DOMNodeContext ? this.context.getItem() : null;
|
|
165
|
+
return new ExtensionScope(changes, this.sessionId, selectedNode);
|
|
166
|
+
}
|
|
167
|
+
|
|
157
168
|
/**
|
|
158
169
|
* Declares a tool to be available to the agent model, verifying first that
|
|
159
170
|
* it hasn't already been declared to prevent duplicate declaration errors.
|
|
@@ -168,9 +179,16 @@ User query: ${enhancedQuery}`;
|
|
|
168
179
|
description: tool.description,
|
|
169
180
|
parameters: tool.parameters,
|
|
170
181
|
displayInfoFromArgs: tool.displayInfoFromArgs,
|
|
171
|
-
handler: args => tool.handler(
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
handler: (args, options) => tool.handler(
|
|
183
|
+
args,
|
|
184
|
+
{
|
|
185
|
+
conversationContext: this.context ?? null,
|
|
186
|
+
changeManager: this.#changes,
|
|
187
|
+
createExtensionScope: this.#createExtensionScope.bind(this),
|
|
188
|
+
execJs: this.#execJs,
|
|
189
|
+
},
|
|
190
|
+
options,
|
|
191
|
+
),
|
|
174
192
|
});
|
|
175
193
|
}
|
|
176
194
|
|
|
@@ -328,24 +328,27 @@ export class AiConversation {
|
|
|
328
328
|
};
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
+
#filterHistoryForNewAgent(): Host.AidaClient.Content[] {
|
|
332
|
+
return this.#agent?.history
|
|
333
|
+
.map(content => {
|
|
334
|
+
return {
|
|
335
|
+
...content,
|
|
336
|
+
parts: content.parts.filter(part => !('functionCall' in part) && !('functionResponse' in part)),
|
|
337
|
+
};
|
|
338
|
+
})
|
|
339
|
+
.filter(content => content.parts.length > 0) ??
|
|
340
|
+
[];
|
|
341
|
+
}
|
|
342
|
+
|
|
331
343
|
#updateAgent(type: ConversationType): void {
|
|
332
344
|
if (this.#type === type) {
|
|
333
345
|
return;
|
|
334
346
|
}
|
|
335
347
|
|
|
336
|
-
this.#type
|
|
348
|
+
const isTransitioningFromStorage = this.#type === ConversationType.STORAGE && type !== ConversationType.STORAGE;
|
|
349
|
+
const history = isTransitioningFromStorage ? [] : this.#filterHistoryForNewAgent();
|
|
337
350
|
|
|
338
|
-
|
|
339
|
-
// as the LLM tries to call the existing ones.
|
|
340
|
-
const history =
|
|
341
|
-
this.#agent?.history
|
|
342
|
-
.map(content => {
|
|
343
|
-
return {
|
|
344
|
-
...content,
|
|
345
|
-
parts: content.parts.filter(part => !('functionCall' in part) && !('functionResponse' in part)),
|
|
346
|
-
};
|
|
347
|
-
})
|
|
348
|
-
.filter(content => content.parts.length > 0);
|
|
351
|
+
this.#type = type;
|
|
349
352
|
|
|
350
353
|
const options = {
|
|
351
354
|
aidaClient: this.#aidaClient,
|
|
@@ -8,6 +8,8 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
8
8
|
import type * as Platform from '../../core/platform/platform.js';
|
|
9
9
|
import * as Root from '../../core/root/root.js';
|
|
10
10
|
|
|
11
|
+
import {debugLog} from './debug.js';
|
|
12
|
+
|
|
11
13
|
const UIStrings = {
|
|
12
14
|
/**
|
|
13
15
|
* @description Message shown to the user if the age check is not successful.
|
|
@@ -71,3 +73,72 @@ export function isSameOrigin(url1: Platform.DevToolsPath.UrlString, url2: Platfo
|
|
|
71
73
|
const origin2 = Common.ParsedURL.ParsedURL.extractOrigin(url2);
|
|
72
74
|
return origin1 !== '' && origin1 === origin2;
|
|
73
75
|
}
|
|
76
|
+
|
|
77
|
+
export interface OneShotPromptRequest {
|
|
78
|
+
aidaClient: Host.AidaClient.AidaClient;
|
|
79
|
+
preamble: string;
|
|
80
|
+
query: string;
|
|
81
|
+
clientFeature: Host.AidaClient.ClientFeature;
|
|
82
|
+
temperature?: number;
|
|
83
|
+
modelId?: string;
|
|
84
|
+
userTier?: string;
|
|
85
|
+
serverSideLoggingEnabled?: boolean;
|
|
86
|
+
signal?: AbortSignal;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function runOneShotPrompt({
|
|
90
|
+
aidaClient,
|
|
91
|
+
preamble,
|
|
92
|
+
query,
|
|
93
|
+
clientFeature,
|
|
94
|
+
temperature,
|
|
95
|
+
modelId,
|
|
96
|
+
userTier,
|
|
97
|
+
serverSideLoggingEnabled,
|
|
98
|
+
signal,
|
|
99
|
+
}: OneShotPromptRequest): Promise<string> {
|
|
100
|
+
const chromeVersion = Root.Runtime.getChromeVersion();
|
|
101
|
+
if (!chromeVersion) {
|
|
102
|
+
throw new Error('Cannot determine Chrome version');
|
|
103
|
+
}
|
|
104
|
+
const disallowLogging = !serverSideLoggingEnabled;
|
|
105
|
+
const sessionId = crypto.randomUUID();
|
|
106
|
+
|
|
107
|
+
const userTierEnum = Host.AidaClient.convertToUserTierEnum(userTier);
|
|
108
|
+
const finalPreamble = userTierEnum === Host.AidaClient.UserTier.TESTERS ? preamble : undefined;
|
|
109
|
+
|
|
110
|
+
const request: Host.AidaClient.DoConversationRequest = {
|
|
111
|
+
client: Host.AidaClient.CLIENT_NAME,
|
|
112
|
+
current_message: {
|
|
113
|
+
parts: [{text: query}],
|
|
114
|
+
role: Host.AidaClient.Role.USER,
|
|
115
|
+
},
|
|
116
|
+
preamble: finalPreamble,
|
|
117
|
+
options: {
|
|
118
|
+
temperature: typeof temperature === 'number' && temperature >= 0 ? temperature : undefined,
|
|
119
|
+
model_id: modelId || undefined,
|
|
120
|
+
},
|
|
121
|
+
metadata: {
|
|
122
|
+
disable_user_content_logging: disallowLogging,
|
|
123
|
+
string_session_id: sessionId,
|
|
124
|
+
user_tier: userTierEnum,
|
|
125
|
+
client_version: chromeVersion,
|
|
126
|
+
},
|
|
127
|
+
functionality_type: Host.AidaClient.FunctionalityType.CHAT,
|
|
128
|
+
client_feature: clientFeature,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
let textResponse = '';
|
|
132
|
+
try {
|
|
133
|
+
for await (const response of aidaClient.doConversation(request, {signal})) {
|
|
134
|
+
if (response.explanation) {
|
|
135
|
+
textResponse = response.explanation;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
debugLog('Error calling AIDA for one-shot prompt', err);
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return textResponse;
|
|
144
|
+
}
|
|
@@ -9,8 +9,6 @@ import type * as Protocol from '../../generated/protocol.js';
|
|
|
9
9
|
|
|
10
10
|
export interface Change {
|
|
11
11
|
groupId: string;
|
|
12
|
-
// Optional turn ID to group changes from the same turn.
|
|
13
|
-
turnId?: number;
|
|
14
12
|
// Optional about where in the source the selector was defined.
|
|
15
13
|
sourceLocation?: string;
|
|
16
14
|
// Selector used by the page or a simple selector as the fallback.
|
|
@@ -104,7 +102,6 @@ export class ChangeManager {
|
|
|
104
102
|
// it currently causes crashes in the Styles tab when duplicate selectors exist (crbug.com/393515428).
|
|
105
103
|
// This workaround avoids that crash.
|
|
106
104
|
existingChange.groupId = change.groupId;
|
|
107
|
-
existingChange.turnId = change.turnId;
|
|
108
105
|
} else {
|
|
109
106
|
changes.push({
|
|
110
107
|
...change,
|
|
@@ -126,11 +123,11 @@ export class ChangeManager {
|
|
|
126
123
|
.join('\n\n');
|
|
127
124
|
}
|
|
128
125
|
|
|
129
|
-
getChangedNodesForGroupId(groupId: string
|
|
126
|
+
getChangedNodesForGroupId(groupId: string): Protocol.DOM.BackendNodeId[] {
|
|
130
127
|
const nodes = new Set<Protocol.DOM.BackendNodeId>();
|
|
131
128
|
for (const changes of this.#stylesheetChanges.values()) {
|
|
132
129
|
for (const change of changes) {
|
|
133
|
-
if (change.groupId === groupId && change.backendNodeId
|
|
130
|
+
if (change.groupId === groupId && change.backendNodeId) {
|
|
134
131
|
nodes.add(change.backendNodeId);
|
|
135
132
|
}
|
|
136
133
|
}
|
package/front_end/models/ai_assistance/{agents/ConversationSummaryAgent.ts → ConversationSummary.ts}
RENAMED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import * as Host from '
|
|
6
|
-
import * as Root from '
|
|
5
|
+
import * as Host from '../../core/host/host.js';
|
|
6
|
+
import * as Root from '../../core/root/root.js';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {runOneShotPrompt} from './AiUtils.js';
|
|
9
9
|
|
|
10
10
|
const preamble = `### Role
|
|
11
11
|
You are a Conversation Summarizer. Your task is to take a transcript of a conversation between a user and a DevTools AI agent and produce a succinct, actionable Markdown summary. This summary will be used to help apply fixes in an IDE, so it must capture all relevant technical details, findings, and proposed code changes without any conversational fluff.
|
|
@@ -98,90 +98,53 @@ color: red;
|
|
|
98
98
|
- Professional, objective, and dense.
|
|
99
99
|
- Past tense for actions; Present tense for technical facts.`;
|
|
100
100
|
|
|
101
|
-
export
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
super();
|
|
105
|
-
this.#conversation = conversation;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
override getURL(): string {
|
|
109
|
-
return 'devtools://ai-assistance';
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
getItem(): string {
|
|
113
|
-
return this.#conversation;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
override getTitle(): string {
|
|
117
|
-
return 'Conversation';
|
|
118
|
-
}
|
|
101
|
+
export interface ConversationSummaryOptions {
|
|
102
|
+
aidaClient: Host.AidaClient.AidaClient;
|
|
103
|
+
serverSideLoggingEnabled?: boolean;
|
|
119
104
|
}
|
|
120
105
|
|
|
121
106
|
/**
|
|
122
|
-
*
|
|
107
|
+
* A class that takes a full conversation between a user and an agent in markdown
|
|
123
108
|
* format and produces a succinct summary of the conversation.
|
|
124
109
|
*
|
|
125
110
|
* This summary is designed to be read by a local agent in the user's IDE and it
|
|
126
111
|
* will be used to help apply fixes to the user's local codebase based on the
|
|
127
112
|
* debugging information the devtools agent found.
|
|
128
|
-
*
|
|
129
|
-
* This agent is not intended to be used directly by users in the AI Assistance
|
|
130
|
-
* panel when chatting with DevTools AI.
|
|
131
113
|
*/
|
|
132
|
-
export class
|
|
133
|
-
|
|
114
|
+
export class ConversationSummary {
|
|
115
|
+
readonly #aidaClient: Host.AidaClient.AidaClient;
|
|
116
|
+
readonly #serverSideLoggingEnabled: boolean;
|
|
134
117
|
|
|
135
|
-
|
|
136
|
-
|
|
118
|
+
constructor(options: ConversationSummaryOptions) {
|
|
119
|
+
this.#aidaClient = options.aidaClient;
|
|
120
|
+
this.#serverSideLoggingEnabled = options.serverSideLoggingEnabled ?? false;
|
|
137
121
|
}
|
|
138
122
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return Root.Runtime.hostConfig.devToolsFreestyler?.userTier;
|
|
142
|
-
}
|
|
123
|
+
async summarizeConversation(conversation: string): Promise<string> {
|
|
124
|
+
const enhancedQuery = `Summarize the following conversation:\n\n${conversation}`;
|
|
143
125
|
|
|
144
|
-
get options(): RequestOptions {
|
|
145
126
|
// TODO(b/491772868): tidy up userTier & feature flags in the backend.
|
|
146
127
|
const temperature = Root.Runtime.hostConfig.devToolsFreestyler?.temperature;
|
|
147
128
|
const modelId = Root.Runtime.hostConfig.devToolsFreestyler?.modelId;
|
|
129
|
+
const userTier = Root.Runtime.hostConfig.devToolsFreestyler?.userTier;
|
|
148
130
|
|
|
149
|
-
|
|
131
|
+
const resultText = await runOneShotPrompt({
|
|
132
|
+
aidaClient: this.#aidaClient,
|
|
133
|
+
preamble,
|
|
134
|
+
query: enhancedQuery,
|
|
135
|
+
clientFeature: Host.AidaClient.ClientFeature.CHROME_CONVERSATION_SUMMARY_AGENT,
|
|
150
136
|
temperature,
|
|
151
137
|
modelId,
|
|
152
|
-
|
|
153
|
-
|
|
138
|
+
userTier,
|
|
139
|
+
serverSideLoggingEnabled: this.#serverSideLoggingEnabled,
|
|
140
|
+
});
|
|
154
141
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
return;
|
|
142
|
+
if (!resultText) {
|
|
143
|
+
throw new Error('Failed to summarize conversation');
|
|
158
144
|
}
|
|
159
145
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
{
|
|
164
|
-
title: 'Conversation transcript',
|
|
165
|
-
text: context.getItem(),
|
|
166
|
-
},
|
|
167
|
-
],
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
override async enhanceQuery(query: string, context: ConversationContext<string>|null): Promise<string> {
|
|
172
|
-
const conversation = context ? context.getItem() : query;
|
|
173
|
-
return `Summarize the following conversation:\n\n${conversation}`;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async summarizeConversation(conversation: string): Promise<string> {
|
|
177
|
-
const context = new ConversationSummaryContext(conversation);
|
|
178
|
-
const response = await Array.fromAsync(this.run('', {selected: context}));
|
|
179
|
-
const lastResponse = response.at(-1);
|
|
180
|
-
if (lastResponse && lastResponse.type === ResponseType.ANSWER && lastResponse.complete === true) {
|
|
181
|
-
const disclaimer =
|
|
182
|
-
'*Note: The code fixes and findings above were identified on a live page in DevTools. When applying them to your codebase, please adapt them to your project\'s specific technical stack (e.g., Tailwind CSS classes, CSS modules, framework components) rather than applying them as literal CSS overrides.*';
|
|
183
|
-
return `${lastResponse.text.trim()}\n\n${disclaimer}`;
|
|
184
|
-
}
|
|
185
|
-
throw new Error('Failed to summarize conversation');
|
|
146
|
+
const disclaimer =
|
|
147
|
+
'*Note: The code fixes and findings above were identified on a live page in DevTools. When applying them to your codebase, please adapt them to your project\'s specific technical stack (e.g., Tailwind CSS classes, CSS modules, framework components) rather than applying them as literal CSS overrides.*';
|
|
148
|
+
return `${resultText.trim()}\n\n${disclaimer}`;
|
|
186
149
|
}
|
|
187
150
|
}
|
|
@@ -34,7 +34,6 @@ export class ExtensionScope {
|
|
|
34
34
|
}) => Promise<void>> = [];
|
|
35
35
|
#changeManager: ChangeManager;
|
|
36
36
|
#agentId: string;
|
|
37
|
-
#turnId?: number;
|
|
38
37
|
/** Don't use directly use the getter */
|
|
39
38
|
#frameId?: Protocol.Page.FrameId|null;
|
|
40
39
|
/** Don't use directly use the getter */
|
|
@@ -42,12 +41,11 @@ export class ExtensionScope {
|
|
|
42
41
|
|
|
43
42
|
readonly #bindingMutex = new Common.Mutex.Mutex();
|
|
44
43
|
|
|
45
|
-
constructor(changes: ChangeManager, agentId: string, selectedNode: SDK.DOMModel.DOMNode|null
|
|
44
|
+
constructor(changes: ChangeManager, agentId: string, selectedNode: SDK.DOMModel.DOMNode|null) {
|
|
46
45
|
this.#changeManager = changes;
|
|
47
46
|
const frameId = selectedNode?.frameId();
|
|
48
47
|
const target = selectedNode?.domModel().target();
|
|
49
48
|
this.#agentId = agentId;
|
|
50
|
-
this.#turnId = turnId;
|
|
51
49
|
this.#target = target;
|
|
52
50
|
this.#frameId = frameId;
|
|
53
51
|
}
|
|
@@ -357,7 +355,6 @@ export class ExtensionScope {
|
|
|
357
355
|
const sanitizedStyles = await this.sanitizedStyleChanges(context.selector, arg.styles);
|
|
358
356
|
const styleChanges = await this.#changeManager.addChange(cssModel, this.frameId, {
|
|
359
357
|
groupId: this.#agentId,
|
|
360
|
-
turnId: this.#turnId,
|
|
361
358
|
sourceLocation: context.sourceLocation,
|
|
362
359
|
selector: context.selector,
|
|
363
360
|
simpleSelector: context.simpleSelector,
|
|
@@ -2,21 +2,12 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import * as Host from '
|
|
6
|
-
import * as Root from '
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import {PerformanceTraceContext} from './PerformanceAgent.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Preamble clocks in at ~970 tokens.
|
|
15
|
-
* The prose is around 4.5 chars per token.
|
|
16
|
-
* The data can be as bad as 1.8 chars per token
|
|
17
|
-
*
|
|
18
|
-
* Check token length in https://aistudio.google.com/
|
|
19
|
-
*/
|
|
5
|
+
import * as Host from '../../core/host/host.js';
|
|
6
|
+
import * as Root from '../../core/root/root.js';
|
|
7
|
+
|
|
8
|
+
import {runOneShotPrompt} from './AiUtils.js';
|
|
9
|
+
import type {AICallTree} from './performance/AICallTree.js';
|
|
10
|
+
|
|
20
11
|
const callTreePreamble = `You are an expert performance analyst embedded within Chrome DevTools.
|
|
21
12
|
You meticulously examine web application behavior captured by the Chrome DevTools Performance Panel and Chrome tracing.
|
|
22
13
|
You will receive a structured text representation of a call tree, derived from a user-selected call frame within a performance trace's flame chart.
|
|
@@ -79,80 +70,6 @@ The 'calculatePosition' function, taking 80ms, is a potential bottleneck.
|
|
|
79
70
|
Consider optimizing the position calculation logic or reducing the frequency of calls to improve animation performance.
|
|
80
71
|
`;
|
|
81
72
|
|
|
82
|
-
export class PerformanceAnnotationsAgent extends AiAgent<AgentFocus> {
|
|
83
|
-
override preamble = callTreePreamble;
|
|
84
|
-
|
|
85
|
-
get clientFeature(): Host.AidaClient.ClientFeature {
|
|
86
|
-
return Host.AidaClient.ClientFeature.CHROME_PERFORMANCE_ANNOTATIONS_AGENT;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
get userTier(): string|undefined {
|
|
90
|
-
return Root.Runtime.hostConfig.devToolsAiAssistancePerformanceAgent?.userTier;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
get options(): RequestOptions {
|
|
94
|
-
const temperature = Root.Runtime.hostConfig.devToolsAiAssistancePerformanceAgent?.temperature;
|
|
95
|
-
const modelId = Root.Runtime.hostConfig.devToolsAiAssistancePerformanceAgent?.modelId;
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
temperature,
|
|
99
|
-
modelId,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async *
|
|
104
|
-
handleContextDetails(context: ConversationContext<AgentFocus>|null): AsyncGenerator<ContextResponse, void, void> {
|
|
105
|
-
if (!context) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const focus = context.getItem();
|
|
110
|
-
if (!focus.callTree) {
|
|
111
|
-
throw new Error('unexpected context');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const callTree = focus.callTree;
|
|
115
|
-
|
|
116
|
-
yield {
|
|
117
|
-
type: ResponseType.CONTEXT,
|
|
118
|
-
details: [
|
|
119
|
-
{
|
|
120
|
-
title: 'Selected call tree',
|
|
121
|
-
text: callTree.serialize(),
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
override async enhanceQuery(query: string, context: ConversationContext<AgentFocus>|null): Promise<string> {
|
|
128
|
-
if (!context) {
|
|
129
|
-
return query;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const focus = context.getItem();
|
|
133
|
-
if (!focus.callTree) {
|
|
134
|
-
throw new Error('unexpected context');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const callTree = focus.callTree;
|
|
138
|
-
const contextString = callTree.serialize();
|
|
139
|
-
return `${contextString}\n\n# User request\n\n${query}`;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Used in the Performance panel to automatically generate a label for a selected entry.
|
|
144
|
-
*/
|
|
145
|
-
async generateAIEntryLabel(callTree: AICallTree): Promise<string> {
|
|
146
|
-
const context = PerformanceTraceContext.fromCallTree(callTree);
|
|
147
|
-
const response = await Array.fromAsync(this.run(AI_LABEL_GENERATION_PROMPT, {selected: context}));
|
|
148
|
-
const lastResponse = response.at(-1);
|
|
149
|
-
if (lastResponse && lastResponse.type === ResponseType.ANSWER && lastResponse.complete === true) {
|
|
150
|
-
return lastResponse.text.trim();
|
|
151
|
-
}
|
|
152
|
-
throw new Error('Failed to generate AI entry label');
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
73
|
const AI_LABEL_GENERATION_PROMPT = `## Instruction:
|
|
157
74
|
Generate a concise label (max 60 chars, single line) describing the *user-visible effect* of the selected call tree's activity, based solely on the provided call tree data.
|
|
158
75
|
|
|
@@ -168,3 +85,44 @@ Generate a concise label (max 60 chars, single line) describing the *user-visibl
|
|
|
168
85
|
- Only include third-party script names if their identification is highly confident.
|
|
169
86
|
- Very important: Only output the 60 character label text, your response will be used in full to show to the user as an annotation in the timeline.
|
|
170
87
|
`;
|
|
88
|
+
|
|
89
|
+
export interface PerformanceAnnotationsOptions {
|
|
90
|
+
aidaClient: Host.AidaClient.AidaClient;
|
|
91
|
+
serverSideLoggingEnabled?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export class PerformanceAnnotations {
|
|
95
|
+
readonly #aidaClient: Host.AidaClient.AidaClient;
|
|
96
|
+
readonly #serverSideLoggingEnabled: boolean;
|
|
97
|
+
|
|
98
|
+
constructor(options: PerformanceAnnotationsOptions) {
|
|
99
|
+
this.#aidaClient = options.aidaClient;
|
|
100
|
+
this.#serverSideLoggingEnabled = options.serverSideLoggingEnabled ?? false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async generateAIEntryLabel(callTree: AICallTree): Promise<string> {
|
|
104
|
+
const contextString = callTree.serialize();
|
|
105
|
+
const query = `${contextString}\n\n# User request\n\n${AI_LABEL_GENERATION_PROMPT}`;
|
|
106
|
+
|
|
107
|
+
const temperature = Root.Runtime.hostConfig.devToolsAiAssistancePerformanceAgent?.temperature;
|
|
108
|
+
const modelId = Root.Runtime.hostConfig.devToolsAiAssistancePerformanceAgent?.modelId;
|
|
109
|
+
const userTier = Root.Runtime.hostConfig.devToolsAiAssistancePerformanceAgent?.userTier;
|
|
110
|
+
|
|
111
|
+
const resultText = await runOneShotPrompt({
|
|
112
|
+
aidaClient: this.#aidaClient,
|
|
113
|
+
preamble: callTreePreamble,
|
|
114
|
+
query,
|
|
115
|
+
clientFeature: Host.AidaClient.ClientFeature.CHROME_PERFORMANCE_ANNOTATIONS_AGENT,
|
|
116
|
+
temperature,
|
|
117
|
+
modelId,
|
|
118
|
+
userTier,
|
|
119
|
+
serverSideLoggingEnabled: this.#serverSideLoggingEnabled,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (!resultText) {
|
|
123
|
+
throw new Error('Failed to generate AI entry label');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return resultText.trim();
|
|
127
|
+
}
|
|
128
|
+
}
|