chrome-devtools-frontend 1.0.1577886 → 1.0.1578729

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.
Files changed (38) hide show
  1. package/front_end/core/common/Revealer.ts +0 -5
  2. package/front_end/core/sdk/ConsoleModel.ts +0 -3
  3. package/front_end/core/sdk/HeapProfilerModel.ts +7 -1
  4. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  5. package/front_end/generated/protocol.ts +2 -2
  6. package/front_end/models/ai_assistance/AiConversation.ts +42 -22
  7. package/front_end/models/issues_manager/CookieIssue.ts +0 -1
  8. package/front_end/models/issues_manager/IssuesManager.ts +2 -15
  9. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +17 -25
  10. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +0 -1
  11. package/front_end/panels/ai_assistance/components/ChatMessage.ts +4 -7
  12. package/front_end/panels/ai_assistance/components/ChatView.ts +1 -1
  13. package/front_end/panels/application/DeviceBoundSessionsView.ts +76 -51
  14. package/front_end/panels/application/preloading/components/RuleSetDetailsView.css +0 -5
  15. package/front_end/panels/console/ConsoleViewMessage.ts +0 -32
  16. package/front_end/panels/console/consoleView.css +0 -5
  17. package/front_end/panels/media/PlayerListView.ts +13 -1
  18. package/front_end/panels/media/playerListView.css +5 -0
  19. package/front_end/panels/network/NetworkItemView.ts +2 -1
  20. package/front_end/panels/network/NetworkLogViewColumns.ts +17 -6
  21. package/front_end/panels/network/RequestInitiatorView.ts +20 -4
  22. package/front_end/panels/network/RequestPayloadView.ts +253 -280
  23. package/front_end/panels/network/ShowMoreDetailsWidget.ts +3 -3
  24. package/front_end/panels/network/requestPayloadTree.css +6 -3
  25. package/front_end/panels/network/requestPayloadView.css +1 -0
  26. package/front_end/panels/security/SecurityPanel.ts +0 -16
  27. package/front_end/panels/security/security-meta.ts +1 -15
  28. package/front_end/panels/settings/keybindsSettingsTab.css +57 -0
  29. package/front_end/panels/sources/CallStackSidebarPane.ts +1 -1
  30. package/front_end/third_party/chromium/README.chromium +1 -1
  31. package/front_end/ui/components/buttons/Button.ts +1 -1
  32. package/front_end/ui/legacy/InspectorView.ts +6 -5
  33. package/front_end/ui/legacy/Treeoutline.ts +81 -22
  34. package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +2 -1
  35. package/front_end/ui/legacy/softDropDown.css +7 -1
  36. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  37. package/mcp/mcp.ts +2 -0
  38. package/package.json +1 -1
@@ -34,10 +34,6 @@ const UIStrings = {
34
34
  * @description The UI destination when right clicking an item that can be revealed
35
35
  */
36
36
  applicationPanel: 'Application panel',
37
- /**
38
- * @description The UI destination when right clicking an item that can be revealed
39
- */
40
- securityPanel: 'Security panel',
41
37
  /**
42
38
  * @description The UI destination when right clicking an item that can be revealed
43
39
  */
@@ -189,7 +185,6 @@ export const RevealerDestination = {
189
185
  TIMELINE_PANEL: i18nLazyString(UIStrings.timelinePanel),
190
186
  APPLICATION_PANEL: i18nLazyString(UIStrings.applicationPanel),
191
187
  SOURCES_PANEL: i18nLazyString(UIStrings.sourcesPanel),
192
- SECURITY_PANEL: i18nLazyString(UIStrings.securityPanel),
193
188
  MEMORY_INSPECTOR_PANEL: i18nLazyString(UIStrings.memoryInspectorPanel),
194
189
  ANIMATIONS_PANEL: i18nLazyString(UIStrings.animationsPanel),
195
190
  };
@@ -545,7 +545,6 @@ export interface ConsoleMessageDetails {
545
545
  context?: string;
546
546
  affectedResources?: AffectedResources;
547
547
  category?: Protocol.Log.LogEntryCategory;
548
- isCookieReportIssue?: boolean;
549
548
  }
550
549
 
551
550
  export class ConsoleMessage {
@@ -569,7 +568,6 @@ export class ConsoleMessage {
569
568
  #exceptionId?: number = undefined;
570
569
  #affectedResources?: AffectedResources;
571
570
  category?: Protocol.Log.LogEntryCategory;
572
- isCookieReportIssue = false;
573
571
 
574
572
  /**
575
573
  * The parent frame of the `console.log` call of logpoints or conditional breakpoints
@@ -600,7 +598,6 @@ export class ConsoleMessage {
600
598
  this.workerId = details?.workerId;
601
599
  this.#affectedResources = details?.affectedResources;
602
600
  this.category = details?.category;
603
- this.isCookieReportIssue = Boolean(details?.isCookieReportIssue);
604
601
 
605
602
  if (!this.#executionContextId && this.#runtimeModel) {
606
603
  if (this.scriptId) {
@@ -11,6 +11,7 @@ import type {RemoteObject} from './RemoteObject.js';
11
11
  import {RuntimeModel} from './RuntimeModel.js';
12
12
  import {SDKModel} from './SDKModel.js';
13
13
  import {Capability, type Target} from './Target.js';
14
+ import {TargetManager} from './TargetManager.js';
14
15
 
15
16
  export class HeapProfilerModel extends SDKModel<EventTypes> {
16
17
  #enabled: boolean;
@@ -106,7 +107,12 @@ export class HeapProfilerModel extends SDKModel<EventTypes> {
106
107
  }
107
108
 
108
109
  async takeHeapSnapshot(heapSnapshotOptions: Protocol.HeapProfiler.TakeHeapSnapshotRequest): Promise<void> {
109
- await this.#heapProfilerAgent.invoke_takeHeapSnapshot(heapSnapshotOptions);
110
+ await TargetManager.instance().suspendAllTargets('heap-snapshot');
111
+ try {
112
+ await this.#heapProfilerAgent.invoke_takeHeapSnapshot(heapSnapshotOptions);
113
+ } finally {
114
+ await TargetManager.instance().resumeAllTargets();
115
+ }
110
116
  }
111
117
 
112
118
  async startTrackingHeapObjects(recordAllocationStacks: boolean): Promise<boolean> {
@@ -783,7 +783,7 @@ inspectorBackend.registerEnum("Network.InterceptionStage", {Request: "Request",
783
783
  inspectorBackend.registerEnum("Network.SignedExchangeErrorField", {SignatureSig: "signatureSig", SignatureIntegrity: "signatureIntegrity", SignatureCertUrl: "signatureCertUrl", SignatureCertSha256: "signatureCertSha256", SignatureValidityUrl: "signatureValidityUrl", SignatureTimestamps: "signatureTimestamps"});
784
784
  inspectorBackend.registerEnum("Network.ContentEncoding", {Deflate: "deflate", Gzip: "gzip", Br: "br", Zstd: "zstd"});
785
785
  inspectorBackend.registerEnum("Network.DirectSocketDnsQueryType", {Ipv4: "ipv4", Ipv6: "ipv6"});
786
- inspectorBackend.registerEnum("Network.PrivateNetworkRequestPolicy", {Allow: "Allow", BlockFromInsecureToMorePrivate: "BlockFromInsecureToMorePrivate", WarnFromInsecureToMorePrivate: "WarnFromInsecureToMorePrivate", PermissionBlock: "PermissionBlock", PermissionWarn: "PermissionWarn"});
786
+ inspectorBackend.registerEnum("Network.LocalNetworkAccessRequestPolicy", {Allow: "Allow", BlockFromInsecureToMorePrivate: "BlockFromInsecureToMorePrivate", WarnFromInsecureToMorePrivate: "WarnFromInsecureToMorePrivate", PermissionBlock: "PermissionBlock", PermissionWarn: "PermissionWarn"});
787
787
  inspectorBackend.registerEnum("Network.IPAddressSpace", {Loopback: "Loopback", Local: "Local", Public: "Public", Unknown: "Unknown"});
788
788
  inspectorBackend.registerEnum("Network.CrossOriginOpenerPolicyValue", {SameOrigin: "SameOrigin", SameOriginAllowPopups: "SameOriginAllowPopups", RestrictProperties: "RestrictProperties", UnsafeNone: "UnsafeNone", SameOriginPlusCoep: "SameOriginPlusCoep", RestrictPropertiesPlusCoep: "RestrictPropertiesPlusCoep", NoopenerAllowPopups: "NoopenerAllowPopups"});
789
789
  inspectorBackend.registerEnum("Network.CrossOriginEmbedderPolicyValue", {None: "None", Credentialless: "Credentialless", RequireCorp: "RequireCorp"});
@@ -913,7 +913,7 @@ inspectorBackend.registerType("Network.DirectTCPSocketOptions", [{"name": "noDel
913
913
  inspectorBackend.registerType("Network.DirectUDPSocketOptions", [{"name": "remoteAddr", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "remotePort", "type": "number", "optional": true, "description": "Unsigned int 16.", "typeRef": null}, {"name": "localAddr", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "localPort", "type": "number", "optional": true, "description": "Unsigned int 16.", "typeRef": null}, {"name": "dnsQueryType", "type": "string", "optional": true, "description": "", "typeRef": "Network.DirectSocketDnsQueryType"}, {"name": "sendBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "receiveBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "multicastLoopback", "type": "boolean", "optional": true, "description": "", "typeRef": null}, {"name": "multicastTimeToLive", "type": "number", "optional": true, "description": "Unsigned int 8.", "typeRef": null}, {"name": "multicastAllowAddressSharing", "type": "boolean", "optional": true, "description": "", "typeRef": null}]);
914
914
  inspectorBackend.registerType("Network.DirectUDPMessage", [{"name": "data", "type": "string", "optional": false, "description": "", "typeRef": null}, {"name": "remoteAddr", "type": "string", "optional": true, "description": "Null for connected mode.", "typeRef": null}, {"name": "remotePort", "type": "number", "optional": true, "description": "Null for connected mode. Expected to be unsigned integer.", "typeRef": null}]);
915
915
  inspectorBackend.registerType("Network.ConnectTiming", [{"name": "requestTime", "type": "number", "optional": false, "description": "Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime. Matches ResourceTiming's requestTime for the same request (but not for redirected requests).", "typeRef": null}]);
916
- inspectorBackend.registerType("Network.ClientSecurityState", [{"name": "initiatorIsSecureContext", "type": "boolean", "optional": false, "description": "", "typeRef": null}, {"name": "initiatorIPAddressSpace", "type": "string", "optional": false, "description": "", "typeRef": "Network.IPAddressSpace"}, {"name": "privateNetworkRequestPolicy", "type": "string", "optional": false, "description": "", "typeRef": "Network.PrivateNetworkRequestPolicy"}]);
916
+ inspectorBackend.registerType("Network.ClientSecurityState", [{"name": "initiatorIsSecureContext", "type": "boolean", "optional": false, "description": "", "typeRef": null}, {"name": "initiatorIPAddressSpace", "type": "string", "optional": false, "description": "", "typeRef": "Network.IPAddressSpace"}, {"name": "localNetworkAccessRequestPolicy", "type": "string", "optional": false, "description": "", "typeRef": "Network.LocalNetworkAccessRequestPolicy"}]);
917
917
  inspectorBackend.registerType("Network.CrossOriginOpenerPolicyStatus", [{"name": "value", "type": "string", "optional": false, "description": "", "typeRef": "Network.CrossOriginOpenerPolicyValue"}, {"name": "reportOnlyValue", "type": "string", "optional": false, "description": "", "typeRef": "Network.CrossOriginOpenerPolicyValue"}, {"name": "reportingEndpoint", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "reportOnlyReportingEndpoint", "type": "string", "optional": true, "description": "", "typeRef": null}]);
918
918
  inspectorBackend.registerType("Network.CrossOriginEmbedderPolicyStatus", [{"name": "value", "type": "string", "optional": false, "description": "", "typeRef": "Network.CrossOriginEmbedderPolicyValue"}, {"name": "reportOnlyValue", "type": "string", "optional": false, "description": "", "typeRef": "Network.CrossOriginEmbedderPolicyValue"}, {"name": "reportingEndpoint", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "reportOnlyReportingEndpoint", "type": "string", "optional": true, "description": "", "typeRef": null}]);
919
919
  inspectorBackend.registerType("Network.ContentSecurityPolicyStatus", [{"name": "effectiveDirectives", "type": "string", "optional": false, "description": "", "typeRef": null}, {"name": "isEnforced", "type": "boolean", "optional": false, "description": "", "typeRef": null}, {"name": "source", "type": "string", "optional": false, "description": "", "typeRef": "Network.ContentSecurityPolicySource"}]);
@@ -11223,7 +11223,7 @@ export namespace Network {
11223
11223
  remotePort?: integer;
11224
11224
  }
11225
11225
 
11226
- export const enum PrivateNetworkRequestPolicy {
11226
+ export const enum LocalNetworkAccessRequestPolicy {
11227
11227
  Allow = 'Allow',
11228
11228
  BlockFromInsecureToMorePrivate = 'BlockFromInsecureToMorePrivate',
11229
11229
  WarnFromInsecureToMorePrivate = 'WarnFromInsecureToMorePrivate',
@@ -11250,7 +11250,7 @@ export namespace Network {
11250
11250
  export interface ClientSecurityState {
11251
11251
  initiatorIsSecureContext: boolean;
11252
11252
  initiatorIPAddressSpace: IPAddressSpace;
11253
- privateNetworkRequestPolicy: PrivateNetworkRequestPolicy;
11253
+ localNetworkAccessRequestPolicy: LocalNetworkAccessRequestPolicy;
11254
11254
  }
11255
11255
 
11256
11256
  export const enum CrossOriginOpenerPolicyValue {
@@ -17,10 +17,10 @@ import {
17
17
  ResponseType
18
18
  } from './agents/AiAgent.js';
19
19
  import {ContextSelectionAgent} from './agents/ContextSelectionAgent.js';
20
- import {FileAgent} from './agents/FileAgent.js';
21
- import {NetworkAgent} from './agents/NetworkAgent.js';
22
- import {PerformanceAgent} from './agents/PerformanceAgent.js';
23
- import {StylingAgent} from './agents/StylingAgent.js';
20
+ import {FileAgent, FileContext} from './agents/FileAgent.js';
21
+ import {NetworkAgent, RequestContext} from './agents/NetworkAgent.js';
22
+ import {PerformanceAgent, PerformanceTraceContext} from './agents/PerformanceAgent.js';
23
+ import {NodeContext, StylingAgent} from './agents/StylingAgent.js';
24
24
  import {AiHistoryStorage, ConversationType, type SerializedConversation} from './AiHistoryStorage.js';
25
25
  import type {ChangeManager} from './ChangeManager.js';
26
26
  import {NetworkRequestFormatter} from './data_formatters/NetworkRequestFormatter.js';
@@ -59,14 +59,17 @@ export class AiConversation {
59
59
  }
60
60
 
61
61
  readonly id: string;
62
- #type: ConversationType;
62
+ // Handled in #updateAgent
63
+ #type!: ConversationType;
64
+ // Handled in #updateAgent
65
+ #agent!: AiAgent<unknown>;
66
+
63
67
  #isReadOnly: boolean;
64
68
  readonly history: ResponseData[];
65
69
  #isExternal: boolean;
66
70
 
67
71
  #aidaClient: Host.AidaClient.AidaClient;
68
72
  #changeManager: ChangeManager|undefined;
69
- #agent: AiAgent<unknown>;
70
73
  #origin?: string;
71
74
 
72
75
  #contexts: Array<ConversationContext<unknown>> = [];
@@ -82,14 +85,13 @@ export class AiConversation {
82
85
  ) {
83
86
  this.#changeManager = changeManager;
84
87
  this.#aidaClient = aidaClient;
85
- this.#type = type;
86
88
 
87
89
  this.id = id;
88
90
  this.#isReadOnly = isReadOnly;
89
91
  this.#isExternal = isExternal;
90
92
  this.history = this.#reconstructHistory(data);
91
93
  // Needs to be last
92
- this.#agent = this.#createAgent();
94
+ this.#updateAgent(type);
93
95
  }
94
96
 
95
97
  get isReadOnly(): boolean {
@@ -123,10 +125,26 @@ export class AiConversation {
123
125
  setContext(updateContext: ConversationContext<unknown>|null): void {
124
126
  if (!updateContext) {
125
127
  this.#contexts = [];
128
+ if (isAiAssistanceContextSelectionAgentEnabled()) {
129
+ this.#updateAgent(ConversationType.NONE);
130
+ }
131
+
126
132
  return;
127
133
  }
128
134
 
129
135
  this.#contexts = [updateContext];
136
+
137
+ if (isAiAssistanceContextSelectionAgentEnabled()) {
138
+ if (updateContext instanceof FileContext) {
139
+ this.#updateAgent(ConversationType.FILE);
140
+ } else if (updateContext instanceof NodeContext) {
141
+ this.#updateAgent(ConversationType.STYLING);
142
+ } else if (updateContext instanceof RequestContext) {
143
+ this.#updateAgent(ConversationType.NETWORK);
144
+ } else if (updateContext instanceof PerformanceTraceContext) {
145
+ this.#updateAgent(ConversationType.PERFORMANCE);
146
+ }
147
+ }
130
148
  }
131
149
 
132
150
  get selectedContext(): ConversationContext<unknown>|undefined {
@@ -249,37 +267,40 @@ export class AiConversation {
249
267
  };
250
268
  }
251
269
 
252
- #createAgent(): AiAgent<unknown> {
270
+ #updateAgent(type: ConversationType): void {
271
+ if (this.#type === type) {
272
+ return;
273
+ }
274
+
275
+ this.#type = type;
253
276
  const options = {
254
277
  aidaClient: this.#aidaClient,
255
278
  serverSideLoggingEnabled: isAiAssistanceServerSideLoggingEnabled(),
256
279
  sessionId: this.id,
257
280
  changeManager: this.#changeManager,
258
281
  };
259
- let agent: AiAgent<unknown>;
260
- switch (this.#type) {
282
+ switch (type) {
261
283
  case ConversationType.STYLING: {
262
- agent = new StylingAgent(options);
284
+ this.#agent = new StylingAgent(options);
263
285
  break;
264
286
  }
265
287
  case ConversationType.NETWORK: {
266
- agent = new NetworkAgent(options);
288
+ this.#agent = new NetworkAgent(options);
267
289
  break;
268
290
  }
269
291
  case ConversationType.FILE: {
270
- agent = new FileAgent(options);
292
+ this.#agent = new FileAgent(options);
271
293
  break;
272
294
  }
273
295
  case ConversationType.PERFORMANCE: {
274
- agent = new PerformanceAgent(options);
296
+ this.#agent = new PerformanceAgent(options);
275
297
  break;
276
298
  }
277
299
  case ConversationType.NONE: {
278
- agent = new ContextSelectionAgent(options);
300
+ this.#agent = new ContextSelectionAgent(options);
279
301
  break;
280
302
  }
281
303
  }
282
- return agent;
283
304
  }
284
305
 
285
306
  #factsCache = new Map<ExtraContext, Host.AidaClient.RequestFact>();
@@ -399,11 +420,6 @@ Time: ${micros(time)}`;
399
420
  },
400
421
  options.multimodalInput,
401
422
  )) {
402
- if (data.type === ResponseType.CONTEXT_CHANGE) {
403
- this.#type = ConversationType.NETWORK;
404
- this.#agent = this.#createAgent();
405
- }
406
-
407
423
  if (shouldAddToHistory(data)) {
408
424
  void this.addHistoryItem(data);
409
425
  }
@@ -439,3 +455,7 @@ function isAiAssistanceServerSideLoggingEnabled(): boolean {
439
455
  type ExtraContext = SDK.DOMModel.DOMNode|SDK.NetworkRequest.NetworkRequest|
440
456
  {event: Trace.Types.Events.Event, traceStartTime: Trace.Types.Timing.Micro}|
441
457
  {insight: Trace.Insights.Types.InsightModel, trace: Trace.TraceModel.ParsedTrace};
458
+
459
+ function isAiAssistanceContextSelectionAgentEnabled(): boolean {
460
+ return Boolean(Root.Runtime.hostConfig.devToolsAiAssistanceContextSelectionAgent?.enabled);
461
+ }
@@ -327,7 +327,6 @@ export class CookieIssue extends Issue<Protocol.Audits.CookieIssueDetails> {
327
327
  Protocol.Log.LogEntryLevel.Warning, UIStrings.consoleTpcdErrorMessage, {
328
328
  url: this.details().request?.url as Platform.DevToolsPath.UrlString | undefined,
329
329
  affectedResources: {requestId: this.details().request?.requestId, issueId: this.issueId},
330
- isCookieReportIssue: true
331
330
  });
332
331
  }
333
332
  return;
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
- import * as Root from '../../core/root/root.js';
7
6
  import * as SDK from '../../core/sdk/sdk.js';
8
7
  import * as Protocol from '../../generated/protocol.js';
9
8
 
@@ -12,7 +11,7 @@ import {BounceTrackingIssue} from './BounceTrackingIssue.js';
12
11
  import {ClientHintIssue} from './ClientHintIssue.js';
13
12
  import {ContentSecurityPolicyIssue} from './ContentSecurityPolicyIssue.js';
14
13
  import {CookieDeprecationMetadataIssue} from './CookieDeprecationMetadataIssue.js';
15
- import {CookieIssue, CookieIssueSubCategory} from './CookieIssue.js';
14
+ import {CookieIssue} from './CookieIssue.js';
16
15
  import {CorsIssue} from './CorsIssue.js';
17
16
  import {CrossOriginEmbedderPolicyIssue, isCrossOriginEmbedderPolicyIssue} from './CrossOriginEmbedderPolicyIssue.js';
18
17
  import {DeprecationIssue} from './DeprecationIssue.js';
@@ -211,7 +210,6 @@ export class IssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
211
210
  #thirdPartyCookiePhaseoutIssueCount = new Map<IssueKind, number>();
212
211
  #issuesById = new Map<string, Issue>();
213
212
  #issuesByOutermostTarget: WeakMap<SDK.Target.Target, Set<Issue>> = new Map();
214
- #thirdPartyCookiePhaseoutIssueMessageSent = false;
215
213
 
216
214
  constructor(
217
215
  private readonly showThirdPartyIssuesSetting?: Common.Settings.Setting<boolean>,
@@ -314,7 +312,6 @@ export class IssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
314
312
 
315
313
  #onIssueAddedEvent(event: Common.EventTarget.EventTargetEvent<SDK.IssuesModel.IssueAddedEvent>): void {
316
314
  const {issuesModel, inspectorIssue} = event.data;
317
- const isPrivacyUiEnabled = Root.Runtime.hostConfig.devToolsPrivacyUI?.enabled;
318
315
 
319
316
  const issues = createIssuesFromProtocolIssue(issuesModel, inspectorIssue);
320
317
  for (const issue of issues) {
@@ -323,16 +320,7 @@ export class IssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
323
320
  if (!message) {
324
321
  continue;
325
322
  }
326
-
327
- // Only show one message for third-party cookie phaseout issues if the new privacy ui is enabled
328
- const is3rdPartyCookiePhaseoutIssue =
329
- CookieIssue.getSubCategory(issue.code()) === CookieIssueSubCategory.THIRD_PARTY_PHASEOUT_COOKIE;
330
- if (!is3rdPartyCookiePhaseoutIssue || !isPrivacyUiEnabled || !this.#thirdPartyCookiePhaseoutIssueMessageSent) {
331
- issuesModel.target().model(SDK.ConsoleModel.ConsoleModel)?.addMessage(message);
332
- }
333
- if (is3rdPartyCookiePhaseoutIssue && isPrivacyUiEnabled) {
334
- this.#thirdPartyCookiePhaseoutIssueMessageSent = true;
335
- }
323
+ issuesModel.target().model(SDK.ConsoleModel.ConsoleModel)?.addMessage(message);
336
324
  }
337
325
  }
338
326
 
@@ -453,7 +441,6 @@ export class IssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
453
441
  this.#issuesById.clear();
454
442
  this.#hiddenIssueCount.clear();
455
443
  this.#thirdPartyCookiePhaseoutIssueCount.clear();
456
- this.#thirdPartyCookiePhaseoutIssueMessageSent = false;
457
444
  const values = this.hideIssueSetting?.get();
458
445
  for (const [key, issue] of this.#allIssues) {
459
446
  if (this.#issueFilter(issue)) {
@@ -729,7 +729,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
729
729
  this.#conversation = conversation;
730
730
  }
731
731
 
732
- this.#conversation?.setContext(this.#getConversationContext(this.#conversation));
732
+ this.#conversation?.setContext(this.#getConversationContext(
733
+ isAiAssistanceContextSelectionAgentEnabled() ? this.#getDefaultConversationType() :
734
+ (this.#conversation?.type ?? null)));
733
735
 
734
736
  this.requestUpdate();
735
737
  }
@@ -1269,12 +1271,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1269
1271
  this.#runAbortController = new AbortController();
1270
1272
  }
1271
1273
 
1272
- #getConversationContext(conversation?: AiAssistanceModel.AiConversation.AiConversation):
1274
+ #getConversationContext(type?: AiAssistanceModel.AiHistoryStorage.ConversationType):
1273
1275
  AiAssistanceModel.AiAgent.ConversationContext<unknown>|null {
1274
- if (!conversation) {
1275
- return null;
1276
- }
1277
- switch (conversation.type) {
1276
+ switch (type) {
1278
1277
  case AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING:
1279
1278
  return this.#selectedElement;
1280
1279
  case AiAssistanceModel.AiHistoryStorage.ConversationType.FILE:
@@ -1284,35 +1283,28 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1284
1283
  case AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE:
1285
1284
  return this.#selectedPerformanceTrace;
1286
1285
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1286
+ case undefined:
1287
1287
  return null;
1288
1288
  }
1289
1289
  }
1290
1290
 
1291
1291
  #handleConversationContextChange = (data: unknown): void => {
1292
1292
  if (data instanceof Workspace.UISourceCode.UISourceCode) {
1293
- if (this.#selectedFile?.getItem() === data) {
1294
- return;
1295
- }
1296
- this.#selectedFile = new AiAssistanceModel.FileAgent.FileContext(data);
1293
+ const context = new AiAssistanceModel.FileAgent.FileContext(data);
1294
+ this.#selectedFile = context;
1297
1295
 
1298
1296
  } else if (data instanceof SDK.DOMModel.DOMNode) {
1299
- if (this.#selectedElement?.getItem() === data ||
1300
- // Ignore non node type like comments or html tags
1301
- data.nodeType() === Node.ELEMENT_NODE) {
1302
- return;
1303
- }
1304
- this.#selectedElement = new AiAssistanceModel.StylingAgent.NodeContext(data);
1297
+ const context = new AiAssistanceModel.StylingAgent.NodeContext(data);
1298
+ this.#selectedElement = context;
1299
+
1305
1300
  } else if (data instanceof SDK.NetworkRequest.NetworkRequest) {
1306
- if (this.#selectedRequest?.getItem() === data) {
1307
- return;
1308
- }
1309
1301
  const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
1310
- this.#selectedRequest = new AiAssistanceModel.NetworkAgent.RequestContext(data, calculator);
1302
+
1303
+ const context = new AiAssistanceModel.NetworkAgent.RequestContext(data, calculator);
1304
+ this.#selectedRequest = context;
1311
1305
  } else if (data instanceof AiAssistanceModel.AIContext.AgentFocus) {
1312
- if (this.#selectedPerformanceTrace?.getItem() === data) {
1313
- return;
1314
- }
1315
- this.#selectedPerformanceTrace = new AiAssistanceModel.PerformanceAgent.PerformanceTraceContext(data);
1306
+ const context = new AiAssistanceModel.PerformanceAgent.PerformanceTraceContext(data);
1307
+ this.#selectedPerformanceTrace = context;
1316
1308
  }
1317
1309
 
1318
1310
  this.#updateConversationState(this.#conversation);
@@ -1329,7 +1321,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1329
1321
  // Cancel any previous in-flight conversation.
1330
1322
  this.#cancel();
1331
1323
  const signal = this.#runAbortController.signal;
1332
- const context = this.#getConversationContext(this.#conversation);
1324
+ const context = this.#getConversationContext(this.#conversation.type);
1333
1325
  this.#conversation.setContext(context);
1334
1326
 
1335
1327
  // If a different context is provided, it must be from the same origin.
@@ -174,7 +174,6 @@ UI.ActionRegistration.registerActionExtension({
174
174
  return new AiAssistance.ActionDelegate();
175
175
  },
176
176
  condition: config => isAnyFeatureAvailable(config) && !isPolicyRestricted(config) && !isGeoRestricted(config),
177
- featurePromotionId: 'debug-with-ai',
178
177
  });
179
178
 
180
179
  UI.ActionRegistration.registerActionExtension({
@@ -323,7 +323,6 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
323
323
  }
324
324
  return renderStep({
325
325
  step: part.step,
326
- isLoading: input.isLoading,
327
326
  markdownRenderer: input.markdownRenderer,
328
327
  isLast: isLastPart,
329
328
  });
@@ -451,12 +450,11 @@ function renderStepDetails({
451
450
  // clang-format on
452
451
  }
453
452
 
454
- function renderStepBadge({step, isLoading, isLast}: {
453
+ function renderStepBadge({step, isLast}: {
455
454
  step: Step,
456
- isLoading: boolean,
457
455
  isLast: boolean,
458
456
  }): Lit.LitTemplate {
459
- if (isLoading && isLast && !step.sideEffect) {
457
+ if (step.isLoading && isLast && !step.sideEffect) {
460
458
  return html`<devtools-spinner></devtools-spinner>`;
461
459
  }
462
460
 
@@ -480,9 +478,8 @@ function renderStepBadge({step, isLoading, isLast}: {
480
478
  ></devtools-icon>`;
481
479
  }
482
480
 
483
- function renderStep({step, isLoading, markdownRenderer, isLast}: {
481
+ function renderStep({step, markdownRenderer, isLast}: {
484
482
  step: Step,
485
- isLoading: boolean,
486
483
  markdownRenderer: MarkdownLitRenderer,
487
484
  isLast: boolean,
488
485
  }): Lit.LitTemplate {
@@ -499,7 +496,7 @@ function renderStep({step, isLoading, markdownRenderer, isLast}: {
499
496
  .open=${Boolean(step.sideEffect)}>
500
497
  <summary>
501
498
  <div class="summary">
502
- ${renderStepBadge({ step, isLoading, isLast })}
499
+ ${renderStepBadge({ step, isLast })}
503
500
  ${renderTitle(step)}
504
501
  <devtools-icon
505
502
  class="arrow"
@@ -105,7 +105,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
105
105
  ${repeat(input.messages, message =>
106
106
  html`<devtools-widget .widgetConfig=${UI.Widget.widgetConfig(ChatMessage, {
107
107
  message,
108
- isLoading: input.isLoading,
108
+ isLoading: input.isLoading && input.messages.at(-1) === message,
109
109
  isReadOnly: input.isReadOnly,
110
110
  canShowFeedbackForm: input.canShowFeedbackForm,
111
111
  userInfo: input.userInfo,