chrome-devtools-frontend 1.0.1611825 → 1.0.1613625

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 (56) hide show
  1. package/.agents/skills/verification/SKILL.md +5 -1
  2. package/front_end/Images/src/flowsheet.svg +1 -0
  3. package/front_end/core/common/Color.ts +3 -2
  4. package/front_end/core/common/MapWithDefault.ts +2 -2
  5. package/front_end/core/common/Object.ts +9 -6
  6. package/front_end/core/platform/StringUtilities.ts +5 -0
  7. package/front_end/core/sdk/NetworkManager.ts +7 -0
  8. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  9. package/front_end/generated/protocol.ts +12 -2
  10. package/front_end/models/ai_assistance/agents/README.md +77 -0
  11. package/front_end/models/greendev/Prototypes.ts +7 -4
  12. package/front_end/models/har/HARFormat.ts +30 -0
  13. package/front_end/models/har/Importer.ts +12 -1
  14. package/front_end/models/har/Log.ts +28 -0
  15. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +6 -4
  16. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +62 -22
  17. package/front_end/panels/ai_assistance/PatchWidget.ts +7 -23
  18. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +3 -3
  19. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +7 -0
  20. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  21. package/front_end/panels/ai_assistance/components/ChatMessage.ts +13 -3
  22. package/front_end/panels/ai_assistance/components/ChatView.ts +4 -0
  23. package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +14 -7
  24. package/front_end/panels/ai_assistance/components/OptInChangeDialog.ts +179 -0
  25. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +4 -3
  26. package/front_end/panels/ai_assistance/components/optInChangeDialog.css +95 -0
  27. package/front_end/panels/ai_assistance/components/walkthroughView.css +1 -1
  28. package/front_end/panels/application/CookieItemsView.ts +3 -2
  29. package/front_end/panels/changes/ChangesView.ts +0 -12
  30. package/front_end/panels/common/common.ts +0 -1
  31. package/front_end/panels/console/ConsolePrompt.ts +2 -2
  32. package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -1
  33. package/front_end/panels/elements/StylesSidebarPane.ts +6 -2
  34. package/front_end/panels/elements/elements-meta.ts +14 -0
  35. package/front_end/panels/emulation/DeviceModeToolbar.ts +13 -4
  36. package/front_end/panels/network/NetworkLogView.ts +58 -28
  37. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +1 -1
  38. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +9 -17
  39. package/front_end/panels/protocol_monitor/JSONEditor.ts +30 -4
  40. package/front_end/panels/recorder/RecorderController.ts +4 -4
  41. package/front_end/panels/recorder/models/RecordingPlayer.ts +1 -1
  42. package/front_end/panels/settings/AISettingsTab.ts +53 -6
  43. package/front_end/panels/settings/SettingsScreen.ts +2 -2
  44. package/front_end/services/puppeteer/PuppeteerConnection.ts +1 -1
  45. package/front_end/third_party/chromium/README.chromium +1 -1
  46. package/front_end/ui/kit/icons/Icon.ts +1 -0
  47. package/front_end/ui/legacy/SplitWidget.ts +9 -6
  48. package/front_end/ui/legacy/TextPrompt.ts +1 -1
  49. package/front_end/ui/legacy/Treeoutline.ts +3 -2
  50. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +4 -3
  51. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +3 -3
  52. package/front_end/ui/legacy/components/source_frame/FontView.ts +101 -88
  53. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -4
  54. package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
  55. package/package.json +2 -2
  56. package/front_end/panels/common/CopyChangesToPrompt.ts +0 -233
@@ -25,9 +25,13 @@ description: MANDATORY: Activate this skill ANY TIME you need to build the proje
25
25
  - `npm run lint` will execute ESLint and StyleLint. It will report any violations and automatically fix them where possible.
26
26
  - To run the linter on a specific file or directory, you can run `npm run lint -- <PATH>` where `PATH` is a path to a file or directory. This will also automatically fix violations where possible.
27
27
 
28
+ ## Presubmit
29
+
30
+ - `git cl presubmit -u` will check if the current change is ready for upload. It will also format and lint the change.
31
+
28
32
  ## Best practices
29
33
 
30
34
  - Run tests often to verify your changes.
31
35
  - Prefer using a fast build, if it exists, to keep the feedback loop shorter.
32
36
  - Periodically compile with TypeScript to check for type errors.
33
- - Run linting at the end of your code changes.
37
+ - Run `git cl presubmit -u` at the end of your code changes.
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="currentColor"><path d="M168-456v192-432V-456Zm383.79 312q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5Zm240-360q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5ZM240-528h204v-72H240v72Zm0 168h204v-72H240v72Zm-72 168q-29.7 0-50.85-21.16Q96-234.32 96-264.04v-432.24Q96-726 117.15-747T168-768h624q29.7 0 50.85 21.15Q864-725.7 864-696H168v432h204v72H168Zm307.5 88.52Q444-134.96 444-179.92 444-215 464-243t52-39v-102h240v-54q-32-11-52-38.92t-20-63.05q0-45.03 31.5-76.53T792-648q45 0 76.5 31.48t31.5 76.44Q900-505 880-477t-52 39v126H588v30q32 11 52 38.92t20 63.05q0 45.03-31.5 76.53T552-72q-45 0-76.5-31.48Z"/></svg>
@@ -684,6 +684,7 @@ export interface Color {
684
684
 
685
685
  const EPSILON = 0.01;
686
686
  const WIDE_RANGE_EPSILON = 1; // For comparisons on channels with a wider range than [0,1]
687
+ const STRICT_EPSILON = 1e-4;
687
688
  function equals(a: number[], b: number[], accuracy?: number): boolean;
688
689
  function equals(a: number|null, b: number|null, accuracy?: number): boolean;
689
690
  function equals(a: number|null|number[], b: number|null|number[], accuracy = EPSILON): boolean {
@@ -994,7 +995,7 @@ export class LCH implements Color {
994
995
  // See "powerless" component definitions in
995
996
  // https://www.w3.org/TR/css-color-4/#specifying-lab-lch
996
997
  isHuePowerless(): boolean {
997
- return equals(this.c, 0);
998
+ return equals(this.c, 0, STRICT_EPSILON);
998
999
  }
999
1000
  static fromSpec(spec: ColorParameterSpec, text: string): LCH|null {
1000
1001
  const L = parsePercentage(spec[0], [0, 100]) ?? parseNumber(spec[0]);
@@ -1592,7 +1593,7 @@ export class HSL implements Color {
1592
1593
  this.l = clamp(l, {min: 0, max: 1});
1593
1594
  s = equals(this.l, 0) || equals(this.l, 1) ? 0 : s;
1594
1595
  this.s = clamp(s, {min: 0, max: 1});
1595
- h = equals(this.s, 0) ? 0 : h;
1596
+ h = equals(this.s, 0, STRICT_EPSILON) ? 0 : h;
1596
1597
  this.h = normalizeHue(h * 360) / 360;
1597
1598
  this.alpha = clamp(alpha ?? null, {min: 0, max: 1});
1598
1599
  this.#authoredText = authoredText;
@@ -8,7 +8,7 @@
8
8
  * TODO: Once the proposal is merged, just replace `MapWithDefault` with `Map` and remove it.
9
9
  **/
10
10
  export class MapWithDefault<K, V> extends Map<K, V> {
11
- getOrInsert(key: K, defaultValue: V): V {
11
+ override getOrInsert(key: K, defaultValue: V): V {
12
12
  if (!this.has(key)) {
13
13
  this.set(key, defaultValue);
14
14
  }
@@ -16,7 +16,7 @@ export class MapWithDefault<K, V> extends Map<K, V> {
16
16
  return this.get(key) as V;
17
17
  }
18
18
 
19
- getOrInsertComputed(key: K, callbackFunction: (key: K) => V): V {
19
+ override getOrInsertComputed(key: K, callbackFunction: (key: K) => V): V {
20
20
  if (!this.has(key)) {
21
21
  this.set(key, callbackFunction(key));
22
22
  }
@@ -119,31 +119,34 @@ export class ObjectWrapper<Events> implements EventTarget<Events> {
119
119
  export function eventMixin<Events, Base extends Platform.Constructor.Constructor<object>>(base: Base) {
120
120
  console.assert(base !== HTMLElement);
121
121
  return class EventHandling extends base implements EventTarget<Events> {
122
- #events = new ObjectWrapper<Events>();
122
+ // Note that the weird name is due to TSC disallowing private/protected fields in
123
+ // anonmous exported classes. We use a `__` prefix to prevent clashes with `base`.
124
+ // eslint-disable-next-line @devtools/no-underscored-properties, @typescript-eslint/naming-convention
125
+ __events = new ObjectWrapper<Events>();
123
126
 
124
127
  addEventListener<T extends keyof Events>(
125
128
  eventType: T, listener: (arg0: EventTargetEvent<Events[T]>) => void,
126
129
  thisObject?: Object): EventDescriptor<Events, T> {
127
- return this.#events.addEventListener(eventType, listener, thisObject);
130
+ return this.__events.addEventListener(eventType, listener, thisObject);
128
131
  }
129
132
 
130
133
  once<T extends keyof Events>(eventType: T): Promise<Events[T]> {
131
- return this.#events.once(eventType);
134
+ return this.__events.once(eventType);
132
135
  }
133
136
 
134
137
  removeEventListener<T extends keyof Events>(
135
138
  eventType: T, listener: (arg0: EventTargetEvent<Events[T]>) => void, thisObject?: Object): void {
136
- this.#events.removeEventListener(eventType, listener, thisObject);
139
+ this.__events.removeEventListener(eventType, listener, thisObject);
137
140
  }
138
141
 
139
142
  hasEventListeners(eventType: keyof Events): boolean {
140
- return this.#events.hasEventListeners(eventType);
143
+ return this.__events.hasEventListeners(eventType);
141
144
  }
142
145
 
143
146
  dispatchEventToListeners<T extends keyof Events>(
144
147
  eventType: Platform.TypeScriptUtilities.NoUnion<T>,
145
148
  ...eventData: EventPayloadToRestParameters<Events, T>): void {
146
- this.#events.dispatchEventToListeners(eventType, ...eventData);
149
+ this.__events.dispatchEventToListeners(eventType, ...eventData);
147
150
  }
148
151
  };
149
152
  }
@@ -276,6 +276,7 @@ export const removeURLFragment = (inputStr: string): string => {
276
276
  };
277
277
 
278
278
  const SPECIAL_REGEX_CHARACTERS = '^[]{}()\\.^$*+?|-,';
279
+ const SPECIAL_URL_PATTERN_CHARACTERS = '?+*(){}\\:';
279
280
 
280
281
  export const regexSpecialCharacters = function(): string {
281
282
  return SPECIAL_REGEX_CHARACTERS;
@@ -450,6 +451,10 @@ export const escapeForRegExp = (str: string): string => {
450
451
  return escapeCharacters(str, SPECIAL_REGEX_CHARACTERS);
451
452
  };
452
453
 
454
+ export const escapeForURLPattern = (text: string): string => {
455
+ return escapeCharacters(text, SPECIAL_URL_PATTERN_CHARACTERS);
456
+ };
457
+
453
458
  export const naturalOrderComparator = (a: string, b: string): number => {
454
459
  const chunk = /^\d+|^\D+/;
455
460
  let chunkA, chunkB, numA, numB;
@@ -32,6 +32,10 @@ const UIStrings = {
32
32
  * @description Explanation why no content is shown for WebSocket connection.
33
33
  */
34
34
  noContentForWebSocket: 'Content for WebSockets is currently not supported',
35
+ /**
36
+ * @description Explanation why no content is shown for Server-Sent Events (SSE).
37
+ */
38
+ noContentForSSE: 'Content for Server-Sent Events (SSE) is currently not supported',
35
39
  /**
36
40
  * @description Explanation why no content is shown for redirect response.
37
41
  */
@@ -215,6 +219,9 @@ export class NetworkManager extends SDKModel<EventTypes> {
215
219
  return {error: i18nString(UIStrings.noContentForWebSocket)};
216
220
  }
217
221
  if (!request.finished) {
222
+ if (Boolean(request.eventSourceMessages()?.length)) {
223
+ return {error: i18nString(UIStrings.noContentForSSE)};
224
+ }
218
225
  await request.once(NetworkRequestEvents.FINISHED_LOADING);
219
226
  }
220
227
  if (request.isRedirect()) {
@@ -867,7 +867,7 @@ inspectorBackend.registerCommand("Network.continueInterceptedRequest", [{"name":
867
867
  inspectorBackend.registerCommand("Network.deleteCookies", [{"name": "name", "type": "string", "optional": false, "description": "Name of the cookies to remove.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "If specified, deletes all the cookies with the given name where domain and path match provided URL.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "If specified, deletes only cookies with the exact domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "If specified, deletes only cookies with the exact path.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "If specified, deletes only cookies with the the given name and partitionKey where all partition key attributes match the cookie partition key attribute.", "typeRef": "Network.CookiePartitionKey"}], [], "Deletes browser cookies with matching name and url or domain/path/partitionKey pair.");
868
868
  inspectorBackend.registerCommand("Network.disable", [], [], "Disables network tracking, prevents network events from being sent to the client.");
869
869
  inspectorBackend.registerCommand("Network.emulateNetworkConditions", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}], [], "Activates emulation of network conditions. This command is deprecated in favor of the emulateNetworkConditionsByRule and overrideNetworkState commands, which can be used together to the same effect.");
870
- inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "matchedNetworkConditions", "type": "array", "optional": false, "description": "Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are also applied for throttling of p2p connections.", "typeRef": "Network.NetworkConditions"}], ["ruleIds"], "Activates emulation of network conditions for individual requests using URL match patterns. Unlike the deprecated Network.emulateNetworkConditions this method does not affect `navigator` state. Use Network.overrideNetworkState to explicitly modify `navigator` behavior.");
870
+ inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional": true, "description": "True to emulate internet disconnection. Deprecated, use the offline property in matchedNetworkConditions or emulateOfflineServiceWorker instead.", "typeRef": null}, {"name": "emulateOfflineServiceWorker", "type": "boolean", "optional": true, "description": "True to emulate offline service worker.", "typeRef": null}, {"name": "matchedNetworkConditions", "type": "array", "optional": false, "description": "Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are also applied for throttling of p2p connections.", "typeRef": "Network.NetworkConditions"}], ["ruleIds"], "Activates emulation of network conditions for individual requests using URL match patterns. Unlike the deprecated Network.emulateNetworkConditions this method does not affect `navigator` state. Use Network.overrideNetworkState to explicitly modify `navigator` behavior.");
871
871
  inspectorBackend.registerCommand("Network.overrideNetworkState", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}], [], "Override the state of navigator.onLine and navigator.connection.");
872
872
  inspectorBackend.registerCommand("Network.enable", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc). This is the maximum number of bytes that will be collected by this DevTools session.", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxPostDataSize", "type": "number", "optional": true, "description": "Longest post body size (in bytes) that would be included in requestWillBeSent notification", "typeRef": null}, {"name": "reportDirectSocketTraffic", "type": "boolean", "optional": true, "description": "Whether DirectSocket chunk send/receive events should be reported.", "typeRef": null}, {"name": "enableDurableMessages", "type": "boolean", "optional": true, "description": "Enable storing response bodies outside of renderer, so that these survive a cross-process navigation. Requires maxTotalBufferSize to be set. Currently defaults to false. This field is being deprecated in favor of the dedicated configureDurableMessages command, due to the possibility of deadlocks when awaiting Network.enable before issuing Runtime.runIfWaitingForDebugger.", "typeRef": null}], [], "Enables network tracking, network events will now be delivered to the client.");
873
873
  inspectorBackend.registerCommand("Network.configureDurableMessages", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}], [], "Configures storing response bodies outside of renderer, so that these survive a cross-process navigation. If maxTotalBufferSize is not set, durable messages are disabled.");
@@ -923,7 +923,7 @@ inspectorBackend.registerType("Network.SignedExchangeSignature", [{"name": "labe
923
923
  inspectorBackend.registerType("Network.SignedExchangeHeader", [{"name": "requestUrl", "type": "string", "optional": false, "description": "Signed exchange request URL.", "typeRef": null}, {"name": "responseCode", "type": "number", "optional": false, "description": "Signed exchange response code.", "typeRef": null}, {"name": "responseHeaders", "type": "object", "optional": false, "description": "Signed exchange response headers.", "typeRef": "Network.Headers"}, {"name": "signatures", "type": "array", "optional": false, "description": "Signed exchange response signature.", "typeRef": "Network.SignedExchangeSignature"}, {"name": "headerIntegrity", "type": "string", "optional": false, "description": "Signed exchange header integrity hash in the form of `sha256-<base64-hash-value>`.", "typeRef": null}]);
924
924
  inspectorBackend.registerType("Network.SignedExchangeError", [{"name": "message", "type": "string", "optional": false, "description": "Error message.", "typeRef": null}, {"name": "signatureIndex", "type": "number", "optional": true, "description": "The index of the signature which caused the error.", "typeRef": null}, {"name": "errorField", "type": "string", "optional": true, "description": "The field which caused the error.", "typeRef": "Network.SignedExchangeErrorField"}]);
925
925
  inspectorBackend.registerType("Network.SignedExchangeInfo", [{"name": "outerResponse", "type": "object", "optional": false, "description": "The outer response of signed HTTP exchange which was received from network.", "typeRef": "Network.Response"}, {"name": "hasExtraInfo", "type": "boolean", "optional": false, "description": "Whether network response for the signed exchange was accompanied by extra headers.", "typeRef": null}, {"name": "header", "type": "object", "optional": true, "description": "Information about the signed exchange header.", "typeRef": "Network.SignedExchangeHeader"}, {"name": "securityDetails", "type": "object", "optional": true, "description": "Security details for the signed exchange header.", "typeRef": "Network.SecurityDetails"}, {"name": "errors", "type": "array", "optional": true, "description": "Errors occurred while handling the signed exchange.", "typeRef": "Network.SignedExchangeError"}]);
926
- inspectorBackend.registerType("Network.NetworkConditions", [{"name": "urlPattern", "type": "string", "optional": false, "description": "Only matching requests will be affected by these conditions. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. If the pattern is empty, all requests are matched (including p2p connections).", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}]);
926
+ inspectorBackend.registerType("Network.NetworkConditions", [{"name": "urlPattern", "type": "string", "optional": false, "description": "Only matching requests will be affected by these conditions. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. If the pattern is empty, all requests are matched (including p2p connections).", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}, {"name": "offline", "type": "boolean", "optional": true, "description": "True to emulate internet disconnection.", "typeRef": null}]);
927
927
  inspectorBackend.registerType("Network.BlockPattern", [{"name": "urlPattern", "type": "string", "optional": false, "description": "URL pattern to match. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. Example: `*://*:*/*.css`.", "typeRef": null}, {"name": "block", "type": "boolean", "optional": false, "description": "Whether or not to block the pattern. If false, a matching request will not be blocked even if it matches a later `BlockPattern`.", "typeRef": null}]);
928
928
  inspectorBackend.registerType("Network.DirectTCPSocketOptions", [{"name": "noDelay", "type": "boolean", "optional": false, "description": "TCP_NODELAY option", "typeRef": null}, {"name": "keepAliveDelay", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"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": "dnsQueryType", "type": "string", "optional": true, "description": "", "typeRef": "Network.DirectSocketDnsQueryType"}]);
929
929
  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}]);
@@ -11376,6 +11376,10 @@ export namespace Network {
11376
11376
  * WebRTC packetReordering feature.
11377
11377
  */
11378
11378
  packetReordering?: boolean;
11379
+ /**
11380
+ * True to emulate internet disconnection.
11381
+ */
11382
+ offline?: boolean;
11379
11383
  }
11380
11384
 
11381
11385
  export interface BlockPattern {
@@ -12154,9 +12158,15 @@ export namespace Network {
12154
12158
 
12155
12159
  export interface EmulateNetworkConditionsByRuleRequest {
12156
12160
  /**
12157
- * True to emulate internet disconnection.
12161
+ * True to emulate internet disconnection. Deprecated, use the offline property in matchedNetworkConditions
12162
+ * or emulateOfflineServiceWorker instead.
12163
+ * @deprecated
12158
12164
  */
12159
- offline: boolean;
12165
+ offline?: boolean;
12166
+ /**
12167
+ * True to emulate offline service worker.
12168
+ */
12169
+ emulateOfflineServiceWorker?: boolean;
12160
12170
  /**
12161
12171
  * Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global
12162
12172
  * conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are
@@ -0,0 +1,77 @@
1
+ # AI Agents
2
+
3
+ This directory contains the implementations of various AI agents used in the AI Assistance panel in Chrome DevTools.
4
+
5
+ ## Performance Agent
6
+
7
+ The `PerformanceAgent` analyzes performance traces. This documentation details the specific data provided to the agent and the data it can retrieve via functions.
8
+
9
+ ### Initial Data Provided to the Agent
10
+
11
+ When a conversation starts or the context changes, the agent is provided with a set of "facts" and query enhancements. This data forms the agent's base knowledge about the trace.
12
+
13
+ #### Trace Facts (Initial Context)
14
+
15
+ Facts are text-based data summaries injected into the conversation. The agent receives:
16
+
17
+ - **Data Schema Descriptions**: Text explaining the format of call frame and network data to help the agent interpret subsequent tool outputs.
18
+ - **Environment State**: Flags indicating if the trace is a fresh recording or loaded from an external file.
19
+ - **Trace Summary Data**: A text summary containing key performance metrics (LCP, INP, CLS) and basic trace metadata.
20
+ - **Critical Requests Data**: A text list of the most critical network requests identified in the trace.
21
+ - **Main Thread Activity Data**: A bottom-up aggregated summary of where time was spent on the main thread.
22
+ - **Longest Tasks Data**: A list of the longest tasks found on the main thread.
23
+ - **Third Party Activity Data**: A summary of time spent on third-party scripts.
24
+
25
+ #### Context Selection (Additional initial context)
26
+
27
+ The agent receives additional initial context based on the user's context selection. The context can be a Trace, an Insight, or a specific Event:
28
+
29
+ - **Trace Context**: No additional context is added beyond the base trace facts.
30
+ - **Insight Context**: The agent receives the name and key of the specific performance insight selected.
31
+ - **Event Context**: The agent receives the serialized details of the specific trace event selected.
32
+
33
+
34
+ ### Data Retrieval Functions (Tools)
35
+
36
+ The agent can request additional data by calling functions. Here is the data the agent receives from each function:
37
+
38
+ #### `getInsightDetails`
39
+ - **Arguments**: `insightSetId` (string), `insightName` (string)
40
+ - **Data Returned to Agent**: A detailed text representation of the specific insight (e.g., LCP breakdown components, render-blocking resource URLs).
41
+
42
+ #### `getEventByKey`
43
+ - **Arguments**: `eventKey` (string)
44
+ - **Data Returned to Agent**: The full JSON representation of the specific trace event.
45
+
46
+ #### `getMainThreadTrackSummary`
47
+ - **Arguments**: `min` (integer, optional), `max` (integer, optional)
48
+ - **Data Returned to Agent**: A comprehensive text summary of main thread activity *within the specified bounds*.
49
+ - **Note**: This differs from the initial "Main Thread Activity Data" fact as it is scoped to the provided time range and includes significantly more data: a **top-down tree**, a **bottom-up tree**, a **third-parties summary**, and a list of **related insights** for events in that range.
50
+
51
+ #### `getNetworkTrackSummary`
52
+ - **Arguments**: `min` (integer, optional), `max` (integer, optional)
53
+ - **Data Returned to Agent**: A text summary of network requests and activity within the bounds.
54
+
55
+ #### `getDetailedCallTree`
56
+ - **Arguments**: `eventKey` (string)
57
+ - **Data Returned to Agent**: A detailed call tree representation for the specified event.
58
+
59
+ #### `addElementAnnotation`
60
+ - **Arguments**: `elementId` (string), `annotationMessage` (string)
61
+ - **Data Returned to Agent**: Confirmation of success or an error message. (Note: This function also modifies the DevTools UI by adding a visual annotation).
62
+
63
+ #### `addNetworkRequestAnnotation`
64
+ - **Arguments**: `eventKey` (string), `annotationMessage` (string)
65
+ - **Data Returned to Agent**: Confirmation of success or an error message. (Note: This function also modifies the DevTools UI by adding a visual annotation).
66
+
67
+ #### `getFunctionCode`
68
+ - **Arguments**: `scriptUrl` (string), `line` (integer), `column` (integer)
69
+ - **Data Returned to Agent**: The source code lines for the function, annotated with performance cost per line if available.
70
+
71
+ #### `getResourceContent`
72
+ - **Arguments**: `url` (string)
73
+ - **Data Returned to Agent**: The full text content of the specified resource (e.g., script file).
74
+
75
+ #### `selectEventByKey`
76
+ - **Arguments**: `eventKey` (string)
77
+ - **Data Returned to Agent**: Confirmation of success or an error message. (Note: This function also modifies the DevTools UI by selecting the event in the flamechart).
@@ -9,7 +9,7 @@ let instance: Prototypes|null = null;
9
9
 
10
10
  export interface GreenDevSettings {
11
11
  aiAnnotations: Common.Settings.Setting<boolean>;
12
- copyToGemini: Common.Settings.Setting<boolean>;
12
+ beyondStyling: Common.Settings.Setting<boolean>;
13
13
  breakpointDebuggerAgent: Common.Settings.Setting<boolean>;
14
14
  emulationCapabilities: Common.Settings.Setting<boolean>;
15
15
  }
@@ -42,8 +42,11 @@ export class Prototypes {
42
42
  false,
43
43
  Common.Settings.SettingStorageType.LOCAL,
44
44
  );
45
- const copyToGemini =
46
- settings.createSetting('greendev-copy-to-gemini-enabled', false, Common.Settings.SettingStorageType.LOCAL);
45
+ const beyondStyling = settings.createSetting(
46
+ 'greendev-beyond-styling-enabled',
47
+ false,
48
+ Common.Settings.SettingStorageType.LOCAL,
49
+ );
47
50
  const breakpointDebuggerAgent = settings.createSetting(
48
51
  'greendev-breakpoint-debugger-agent-enabled',
49
52
  false,
@@ -55,6 +58,6 @@ export class Prototypes {
55
58
  Common.Settings.SettingStorageType.LOCAL,
56
59
  );
57
60
 
58
- return {aiAnnotations, copyToGemini, breakpointDebuggerAgent, emulationCapabilities};
61
+ return {aiAnnotations, beyondStyling, breakpointDebuggerAgent, emulationCapabilities};
59
62
  }
60
63
  }
@@ -171,6 +171,7 @@ export class HAREntry extends HARBase {
171
171
  this.custom.set('initiator', this.importInitiator(data['_initiator']));
172
172
  this.custom.set('priority', HARBase.optionalString(data['_priority']));
173
173
  this.custom.set('resourceType', HARBase.optionalString(data['_resourceType']));
174
+ this.custom.set('eventSourceMessages', this.#importEventSourceMessages(data['_eventSourceMessages']));
174
175
  this.custom.set('webSocketMessages', this.importWebSocketMessages(data['_webSocketMessages']));
175
176
  }
176
177
 
@@ -196,6 +197,21 @@ export class HAREntry extends HARBase {
196
197
  }
197
198
  return outputMessages;
198
199
  }
200
+
201
+ #importEventSourceMessages(inputMessages: any): HAREventSourceMessage[]|undefined {
202
+ if (!Array.isArray(inputMessages)) {
203
+ return;
204
+ }
205
+
206
+ const outputMessages = [];
207
+ for (const message of inputMessages) {
208
+ if (typeof message !== 'object') {
209
+ return;
210
+ }
211
+ outputMessages.push(new HAREventSourceMessage(message));
212
+ }
213
+ return outputMessages;
214
+ }
199
215
  }
200
216
 
201
217
  class HARRequest extends HARBase {
@@ -480,3 +496,17 @@ class HARWebSocketMessage extends HARBase {
480
496
  this.type = HARBase.optionalString(data['type']);
481
497
  }
482
498
  }
499
+
500
+ class HAREventSourceMessage extends HARBase {
501
+ time: number|undefined;
502
+ eventName: string|undefined;
503
+ eventId: string|undefined;
504
+ data: string|undefined;
505
+ constructor(data: any) {
506
+ super(data);
507
+ this.time = HARBase.optionalNumber(data['time']);
508
+ this.eventName = HARBase.optionalString(data['eventName']);
509
+ this.eventId = HARBase.optionalString(data['eventId']);
510
+ this.data = HARBase.optionalString(data['data']);
511
+ }
512
+ }
@@ -137,7 +137,18 @@ export class Importer {
137
137
  async () =>
138
138
  new TextUtils.ContentData.ContentData(contentText ?? '', isBase64, mimeType ?? '', charset ?? undefined));
139
139
 
140
- if (request.mimeType === Platform.MimeType.MimeType.EVENTSTREAM && contentText) {
140
+ const importedEventSourceMessages = entry.customAsArray('eventSourceMessages');
141
+
142
+ if (importedEventSourceMessages) {
143
+ for (const message of importedEventSourceMessages) {
144
+ if (message.time === undefined || message.eventName === undefined || message.eventId === undefined) {
145
+ continue;
146
+ }
147
+ // message.data may be undefined, if saved in a sanitized context
148
+
149
+ request.addEventSourceMessage(message.time, message.eventName, message.eventId, message.data);
150
+ }
151
+ } else if (request.mimeType === Platform.MimeType.MimeType.EVENTSTREAM && contentText) {
141
152
  const issueTime = entry.startedDateTime.getTime() / 1000;
142
153
  const onEvent = (eventName: string, data: string, eventId: string): void => {
143
154
  request.addEventSourceMessage(issueTime, eventName, eventId, data);
@@ -176,6 +176,26 @@ export class Entry {
176
176
  delete entry._webSocketMessages;
177
177
  }
178
178
 
179
+ const eventSourceMessages = harEntry.request.eventSourceMessages();
180
+ if (eventSourceMessages?.length) {
181
+ const messages = [];
182
+ for (const message of eventSourceMessages) {
183
+ const messageDTO: EventSourceMessageDTO = {
184
+ time: message.time,
185
+ eventName: message.eventName,
186
+ eventId: message.eventId,
187
+ };
188
+ if (!options.sanitize) {
189
+ // Omit the data when sanitizing, as it could contain sensitive information.
190
+ messageDTO.data = message.data;
191
+ }
192
+ messages.push(messageDTO);
193
+ }
194
+ entry._eventSourceMessages = messages;
195
+ } else {
196
+ delete entry._eventSourceMessages;
197
+ }
198
+
179
199
  return entry;
180
200
  }
181
201
 
@@ -490,6 +510,7 @@ export interface EntryDTO {
490
510
  _priority: Protocol.Network.ResourcePriority|null;
491
511
  _resourceType: string;
492
512
  _webSocketMessages?: Object[];
513
+ _eventSourceMessages?: EventSourceMessageDTO[];
493
514
  cache: Object;
494
515
  connection?: string;
495
516
  pageref?: string;
@@ -540,3 +561,10 @@ export interface LogDTO {
540
561
  pages: Page[];
541
562
  entries: EntryDTO[];
542
563
  }
564
+
565
+ export interface EventSourceMessageDTO {
566
+ time: number;
567
+ eventName: string;
568
+ eventId: string;
569
+ data?: string;
570
+ }
@@ -17,13 +17,15 @@ export class HeapSnapshotWorkerProxy extends Common.ObjectWrapper.ObjectWrapper<
17
17
  readonly previousCallbacks = new Set<number>();
18
18
  readonly worker: PlatformApi.HostRuntime.Worker;
19
19
  interval?: number;
20
+ readonly workerUrl?: string;
20
21
 
21
- constructor(eventHandler: (arg0: string, arg1: string) => void) {
22
+ constructor(eventHandler: (arg0: string, arg1: string) => void, workerUrl?: string) {
22
23
  super();
23
24
  this.eventHandler = eventHandler;
25
+ this.workerUrl = workerUrl;
24
26
  this.worker = Platform.HostRuntime.HOST_RUNTIME.createWorker(
25
- new URL('../../entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.js', import.meta.url)
26
- .toString());
27
+ workerUrl ?? import.meta.resolve('../../entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.js'),
28
+ );
27
29
  this.worker.onmessage = this.messageReceived.bind(this);
28
30
  }
29
31
 
@@ -236,7 +238,7 @@ export class HeapSnapshotLoaderProxy extends HeapSnapshotProxyObject implements
236
238
 
237
239
  async close(): Promise<void> {
238
240
  await this.callMethodPromise('close');
239
- const secondWorker = new HeapSnapshotWorkerProxy(() => {});
241
+ const secondWorker = new HeapSnapshotWorkerProxy(() => {}, this.worker.workerUrl);
240
242
  const channel = new MessageChannel();
241
243
  await secondWorker.setupForSecondaryInit(channel.port2);
242
244
  const snapshotProxy = await this.callFactoryMethodPromise('buildSnapshot', HeapSnapshotProxy, [channel.port1]);
@@ -44,6 +44,7 @@ import {
44
44
  import {DisabledWidget} from './components/DisabledWidget.js';
45
45
  import {ExploreWidget} from './components/ExploreWidget.js';
46
46
  import {MarkdownRendererWithCodeBlock} from './components/MarkdownRendererWithCodeBlock.js';
47
+ import {OptInChangeDialog} from './components/OptInChangeDialog.js';
47
48
  import {PerformanceAgentMarkdownRenderer} from './components/PerformanceAgentMarkdownRenderer.js';
48
49
  import {StylingAgentMarkdownRenderer} from './components/StylingAgentMarkdownRenderer.js';
49
50
  import {
@@ -252,6 +253,16 @@ const UIStringsNotTranslate = {
252
253
  */
253
254
  inputDisclaimerForAccessibilityEnterpriseNoLogging:
254
255
  'Chat messages and the selected Lighthouse report are sent to Google. The content you submit and that is generated by this feature will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
256
+ /**
257
+ * @description Disclaimer text right after the chat input when V2 is enabled.
258
+ */
259
+ inputDisclaimerV2:
260
+ 'Chat messages, data accessible for this site via DevTools panels and Web APIs, and items you select such as network requests, files, and performance traces are sent to Google and may be seen by human reviewers to improve this feature. This is an experimental AI feature and won’t always get it right.',
261
+ /**
262
+ * @description Disclaimer text right after the chat input when V2 is enabled and enterprise logging is off.
263
+ */
264
+ inputDisclaimerEnterpriseNoLoggingV2:
265
+ 'Chat messages, data accessible for this site via DevTools panels and Web APIs, and items you select such as network requests, files, and performance traces are sent to Google. The content submitted to and generated by this feature will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
255
266
  } as const;
256
267
 
257
268
  const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/AiAssistancePanel.ts', UIStrings);
@@ -779,11 +790,32 @@ export class AiAssistancePanel extends UI.Panel.Panel {
779
790
  return await this.#conversationSummaryAgent.summarizeConversation(markdown);
780
791
  },
781
792
  onTextSubmit: async (
782
-
783
793
  text: string, imageInput?: Host.AidaClient.Part,
784
794
  multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
785
- Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
786
- await this.#startConversation(text, imageInput, multimodalInputType);
795
+ const submit = (): void => {
796
+ Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
797
+ void this.#startConversation(text, imageInput, multimodalInputType);
798
+ };
799
+
800
+ const isAIV2Enabled = Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled;
801
+ const seenSetting =
802
+ Common.Settings.Settings.instance().moduleSetting('ai-assistance-v2-opt-in-change-dialog-seen');
803
+ if (isAIV2Enabled && !seenSetting.get()) {
804
+ OptInChangeDialog.show({
805
+ onGotIt: () => {
806
+ seenSetting.set(true);
807
+ submit();
808
+ },
809
+ onManageSettings: () => {
810
+ seenSetting.set(true);
811
+ this.#viewOutput.chatView?.setInputValue(text);
812
+ void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
813
+ },
814
+ });
815
+ return;
816
+ }
817
+
818
+ submit();
787
819
  },
788
820
  onInspectElementClick: this.#handleSelectElementClick.bind(this),
789
821
  onFeedbackSubmit: this.#handleFeedbackSubmit.bind(this),
@@ -1396,46 +1428,54 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1396
1428
  return i18nString(UIStrings.inputDisclaimerForEmptyState);
1397
1429
  }
1398
1430
 
1399
- const noLogging = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue ===
1431
+ const loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
1400
1432
  Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
1433
+
1434
+ if (Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled) {
1435
+ if (loggingEnabled) {
1436
+ return lockedString(UIStringsNotTranslate.inputDisclaimerV2);
1437
+ }
1438
+ return lockedString(UIStringsNotTranslate.inputDisclaimerEnterpriseNoLoggingV2);
1439
+ }
1440
+
1401
1441
  switch (this.#conversation.type) {
1402
1442
  case AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING:
1403
- if (noLogging) {
1404
- return lockedString(UIStringsNotTranslate.inputDisclaimerForStylingEnterpriseNoLogging);
1443
+ if (loggingEnabled) {
1444
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForStyling);
1405
1445
  }
1406
- return lockedString(UIStringsNotTranslate.inputDisclaimerForStyling);
1446
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForStylingEnterpriseNoLogging);
1407
1447
  case AiAssistanceModel.AiHistoryStorage.ConversationType.FILE:
1408
- if (noLogging) {
1409
- return lockedString(UIStringsNotTranslate.inputDisclaimerForFileEnterpriseNoLogging);
1448
+ if (loggingEnabled) {
1449
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForFile);
1410
1450
  }
1411
- return lockedString(UIStringsNotTranslate.inputDisclaimerForFile);
1451
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForFileEnterpriseNoLogging);
1412
1452
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK:
1413
- if (noLogging) {
1414
- return lockedString(UIStringsNotTranslate.inputDisclaimerForNetworkEnterpriseNoLogging);
1453
+ if (loggingEnabled) {
1454
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForNetwork);
1415
1455
  }
1416
- return lockedString(UIStringsNotTranslate.inputDisclaimerForNetwork);
1456
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForNetworkEnterpriseNoLogging);
1417
1457
 
1418
1458
  // It is deliberate that both Performance agents use the same disclaimer
1419
1459
  // text and this has been approved by Privacy.
1420
1460
  case AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE:
1421
- if (noLogging) {
1422
- return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformanceEnterpriseNoLogging);
1461
+ if (loggingEnabled) {
1462
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformance);
1423
1463
  }
1424
- return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformance);
1464
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformanceEnterpriseNoLogging);
1425
1465
 
1426
1466
  case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
1427
- if (noLogging) {
1428
- return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibilityEnterpriseNoLogging);
1467
+ if (loggingEnabled) {
1468
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibility);
1429
1469
  }
1430
- return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibility);
1470
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibilityEnterpriseNoLogging);
1431
1471
 
1432
1472
  case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1433
1473
 
1434
1474
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1435
- if (noLogging) {
1436
- return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContextEnterpriseNoLogging);
1475
+ if (loggingEnabled) {
1476
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContext);
1437
1477
  }
1438
- return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContext);
1478
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContextEnterpriseNoLogging);
1439
1479
  }
1440
1480
  }
1441
1481