chrome-devtools-frontend 1.0.1582745 → 1.0.1585538

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 (127) hide show
  1. package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
  2. package/front_end/core/host/InspectorFrontendHostStub.ts +2 -0
  3. package/front_end/core/root/Runtime.ts +12 -11
  4. package/front_end/core/sdk/CSSMatchedStyles.ts +3 -0
  5. package/front_end/core/sdk/CSSMetadata.ts +3 -0
  6. package/front_end/core/sdk/NetworkManager.ts +63 -115
  7. package/front_end/entrypoint_template.html +1 -5
  8. package/front_end/entrypoints/main/MainImpl.ts +1 -0
  9. package/front_end/generated/Deprecation.ts +21 -0
  10. package/front_end/generated/InspectorBackendCommands.ts +5 -3
  11. package/front_end/generated/SupportedCSSProperties.js +6 -2
  12. package/front_end/generated/protocol-mapping.d.ts +2 -1
  13. package/front_end/generated/protocol-proxy-api.d.ts +2 -1
  14. package/front_end/generated/protocol.ts +14 -0
  15. package/front_end/models/ai_assistance/AiConversation.ts +34 -2
  16. package/front_end/models/ai_assistance/BuiltInAi.ts +1 -2
  17. package/front_end/models/ai_assistance/agents/AiAgent.ts +3 -10
  18. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +1 -1
  19. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +17 -9
  20. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -24
  21. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +5 -0
  22. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +16 -8
  23. package/front_end/models/computed_style/ComputedStyleModel.ts +20 -15
  24. package/front_end/models/greendev/Prototypes.ts +1 -5
  25. package/front_end/models/issues_manager/CorsIssue.ts +2 -9
  26. package/front_end/models/issues_manager/descriptions/corsLocalNetworkAccessPermissionDenied.md +2 -2
  27. package/front_end/models/javascript_metadata/NativeFunctions.js +20 -0
  28. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +28 -39
  29. package/front_end/panels/ai_assistance/components/ChatInput.ts +73 -95
  30. package/front_end/panels/ai_assistance/components/ChatMessage.ts +4 -2
  31. package/front_end/panels/ai_assistance/components/ChatView.ts +0 -2
  32. package/front_end/panels/autofill/AutofillView.ts +4 -8
  33. package/front_end/panels/common/AiCodeGenerationTeaser.ts +37 -8
  34. package/front_end/panels/console/ConsoleView.ts +1 -2
  35. package/front_end/panels/console/ConsoleViewMessage.ts +18 -11
  36. package/front_end/panels/elements/ComputedStyleWidget.ts +80 -48
  37. package/front_end/panels/elements/ElementStatePaneWidget.ts +1 -1
  38. package/front_end/panels/elements/ElementsPanel.ts +18 -5
  39. package/front_end/panels/elements/ElementsTreeElement.ts +459 -435
  40. package/front_end/panels/elements/EventListenersWidget.ts +2 -4
  41. package/front_end/panels/elements/NodeStackTraceWidget.ts +1 -3
  42. package/front_end/panels/elements/PropertiesWidget.ts +1 -2
  43. package/front_end/panels/elements/StylePropertyTreeElement.ts +18 -2
  44. package/front_end/panels/elements/computedStyleWidget.css +25 -0
  45. package/front_end/panels/issues/AffectedResourcesView.ts +1 -2
  46. package/front_end/panels/network/NetworkDataGridNode.ts +0 -8
  47. package/front_end/panels/network/NetworkLogView.ts +64 -105
  48. package/front_end/panels/network/RequestConditionsDrawer.ts +168 -233
  49. package/front_end/panels/network/network-meta.ts +4 -27
  50. package/front_end/panels/settings/SettingsScreen.ts +12 -4
  51. package/front_end/panels/settings/WorkspaceSettingsTab.ts +1 -1
  52. package/front_end/panels/snippets/SnippetsQuickOpen.ts +6 -9
  53. package/front_end/panels/sources/CallStackSidebarPane.ts +6 -8
  54. package/front_end/panels/sources/DebuggerPlugin.ts +2 -1
  55. package/front_end/panels/sources/GoToLineQuickOpen.ts +0 -4
  56. package/front_end/panels/sources/OpenFileQuickOpen.ts +0 -4
  57. package/front_end/panels/sources/OutlineQuickOpen.ts +0 -4
  58. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +3 -1
  59. package/front_end/panels/sources/sources-meta.ts +9 -6
  60. package/front_end/panels/timeline/TimelineFlameChartView.ts +0 -12
  61. package/front_end/panels/timeline/TimelinePanel.ts +35 -15
  62. package/front_end/panels/timeline/components/Sidebar.ts +21 -0
  63. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +1 -20
  64. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +0 -1
  65. package/front_end/third_party/chromium/README.chromium +1 -1
  66. package/front_end/third_party/puppeteer/README.chromium +2 -2
  67. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +2 -3
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.d.ts.map +1 -1
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.js +5 -3
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.js.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +8 -6
  82. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  86. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +2 -3
  88. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  91. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.d.ts.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.js +5 -3
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.js.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  96. package/front_end/third_party/puppeteer/package/package.json +4 -4
  97. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +1 -1
  98. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +2 -2
  99. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +4 -3
  100. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  101. package/front_end/third_party/puppeteer/package/src/util/encoding.ts +5 -3
  102. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  103. package/front_end/ui/components/linkifier/LinkifierImpl.ts +3 -0
  104. package/front_end/ui/components/linkifier/LinkifierUtils.ts +3 -0
  105. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +8 -0
  106. package/front_end/ui/components/text_editor/AiCodeGenerationParser.ts +29 -7
  107. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +42 -18
  108. package/front_end/ui/components/text_editor/config.ts +6 -0
  109. package/front_end/ui/legacy/InspectorView.ts +41 -15
  110. package/front_end/ui/legacy/Toolbar.ts +12 -4
  111. package/front_end/ui/legacy/UIUtils.ts +56 -7
  112. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +4 -3
  113. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +2 -1
  114. package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +8 -2
  115. package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +8 -8
  116. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +12 -9
  117. package/front_end/ui/legacy/components/utils/Linkifier.ts +116 -87
  118. package/front_end/ui/legacy/legacy.ts +0 -2
  119. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
  120. package/mcp/HostBindings.ts +3 -0
  121. package/package.json +1 -1
  122. package/front_end/models/issues_manager/descriptions/corsInsecurePrivateNetwork.md +0 -10
  123. package/front_end/models/issues_manager/descriptions/corsPreflightAllowPrivateNetworkError.md +0 -10
  124. package/front_end/models/issues_manager/descriptions/corsPrivateNetworkPermissionDenied.md +0 -10
  125. package/front_end/panels/elements/computedStyleSidebarPane.css +0 -18
  126. package/front_end/ui/legacy/Floaty.ts +0 -438
  127. package/front_end/ui/legacy/floaty.css +0 -77
@@ -13,7 +13,6 @@ import * as SDK from '../../core/sdk/sdk.js';
13
13
  import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
14
14
  import * as Annotations from '../../models/annotations/annotations.js';
15
15
  import * as Badges from '../../models/badges/badges.js';
16
- import * as GreenDev from '../../models/greendev/greendev.js';
17
16
  import * as TextUtils from '../../models/text_utils/text_utils.js';
18
17
  import type * as Trace from '../../models/trace/trace.js';
19
18
  import * as Workspace from '../../models/workspace/workspace.js';
@@ -518,7 +517,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
518
517
  };
519
518
  #timelinePanelInstance: TimelinePanel.TimelinePanel.TimelinePanel|null = null;
520
519
  #runAbortController = new AbortController();
521
- #additionalContextItemsFromFloaty: UI.Floaty.FloatyContextSelection[] = [];
522
520
 
523
521
  constructor(private view: View = defaultView, {aidaClient, aidaAvailability, syncInfo}: {
524
522
  aidaClient: Host.AidaClient.AidaClient,
@@ -571,7 +569,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
571
569
  return {
572
570
  state: ViewState.CHAT_VIEW,
573
571
  props: {
574
- additionalFloatyContext: this.#additionalContextItemsFromFloaty,
575
572
  blockedByCrossOrigin: this.#conversation.isBlockedByOrigin,
576
573
  isLoading: this.#isLoading,
577
574
  messages: this.#messages,
@@ -665,15 +662,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
665
662
  }
666
663
  }
667
664
 
668
- #bindFloatyListener(): void {
669
- const additionalContexts = UI.Context.Context.instance().flavor(UI.Floaty.FloatyFlavor);
670
- if (!additionalContexts) {
671
- return;
672
- }
673
- this.#additionalContextItemsFromFloaty = additionalContexts.selectedContexts;
674
- this.requestUpdate();
675
- }
676
-
677
665
  async #handlePerformanceRecordAndReload(): Promise<Trace.TraceModel.ParsedTrace> {
678
666
  return await TimelinePanel.TimelinePanel.TimelinePanel.executeRecordAndReload();
679
667
  }
@@ -707,12 +695,24 @@ export class AiAssistancePanel extends UI.Panel.Panel {
707
695
  // We select the default agent based on the open panels if
708
696
  // there isn't any active conversation.
709
697
  #selectDefaultAgentIfNeeded(): void {
698
+ // We don't change the current agent when there is a message in flight.
699
+ if (this.#isLoading) {
700
+ return;
701
+ }
702
+
710
703
  // If there already is an agent and if it is not empty,
711
- // we don't automatically change the agent. In addition to this,
712
- // we don't change the current agent when there is a message in flight.
713
- if ((this.#conversation && !this.#conversation.isEmpty) || this.#isLoading) {
704
+ // we don't automatically change the agent.
705
+ if (this.#conversation && !this.#conversation.isEmpty) {
706
+ // If the context selection agent is enabled,
707
+ // we update the context of the current agent.
708
+ const context = this.#getConversationContext(this.#getDefaultConversationType());
709
+ if (context && isAiAssistanceContextSelectionAgentEnabled()) {
710
+ this.#conversation?.setContext(context);
711
+ this.requestUpdate();
712
+ }
714
713
  return;
715
714
  }
715
+
716
716
  const targetConversationType = this.#getDefaultConversationType();
717
717
  if (this.#conversation?.type === targetConversationType) {
718
718
  // The above if makes sure even if we have an active agent it's empty
@@ -722,7 +722,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
722
722
  const conversation = targetConversationType ?
723
723
  new AiAssistanceModel.AiConversation.AiConversation(
724
724
  targetConversationType, [], undefined, false, this.#aidaClient, this.#changeManager, false,
725
- this.#handlePerformanceRecordAndReload.bind(this), this.#handleInspectElement.bind(this)) :
725
+ this.#handlePerformanceRecordAndReload.bind(this), this.#handleInspectElement.bind(this),
726
+ NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator()) :
726
727
  undefined;
727
728
 
728
729
  this.#updateConversationState(conversation);
@@ -751,6 +752,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
751
752
  false,
752
753
  this.#handlePerformanceRecordAndReload.bind(this),
753
754
  this.#handleInspectElement.bind(this),
755
+ NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
754
756
  );
755
757
  }
756
758
  }
@@ -812,11 +814,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
812
814
  this.#selectDefaultAgentIfNeeded();
813
815
 
814
816
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistancePanelOpened);
815
-
816
- if (GreenDev.Prototypes.instance().isEnabled('inDevToolsFloaty')) {
817
- UI.Context.Context.instance().addFlavorChangeListener(UI.Floaty.FloatyFlavor, this.#bindFloatyListener, this);
818
- this.#bindFloatyListener();
819
- }
820
817
  }
821
818
 
822
819
  override willHide(): void {
@@ -1218,6 +1215,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1218
1215
  false,
1219
1216
  this.#handlePerformanceRecordAndReload.bind(this),
1220
1217
  this.#handleInspectElement.bind(this),
1218
+ NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
1221
1219
  );
1222
1220
  }
1223
1221
  this.#updateConversationState(conversation);
@@ -1346,23 +1344,14 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1346
1344
  }
1347
1345
 
1348
1346
  #handleConversationContextChange = (data: unknown): void => {
1349
- if (data instanceof Workspace.UISourceCode.UISourceCode) {
1350
- const context = new AiAssistanceModel.FileAgent.FileContext(data);
1351
- this.#selectedFile = context;
1352
- this.#conversation?.setContext(context);
1353
- } else if (data instanceof SDK.DOMModel.DOMNode) {
1354
- const context = new AiAssistanceModel.StylingAgent.NodeContext(data);
1355
- this.#selectedElement = context;
1356
- this.#conversation?.setContext(context);
1357
- } else if (data instanceof SDK.NetworkRequest.NetworkRequest) {
1358
- const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
1359
- const context = new AiAssistanceModel.NetworkAgent.RequestContext(data, calculator);
1360
- this.#selectedRequest = context;
1361
- this.#conversation?.setContext(context);
1362
- } else if (data instanceof AiAssistanceModel.AIContext.AgentFocus) {
1363
- const context = new AiAssistanceModel.PerformanceAgent.PerformanceTraceContext(data);
1364
- this.#selectedPerformanceTrace = context;
1365
- this.#conversation?.setContext(context);
1347
+ if (data instanceof AiAssistanceModel.FileAgent.FileContext) {
1348
+ this.#selectedFile = data;
1349
+ } else if (data instanceof AiAssistanceModel.StylingAgent.NodeContext) {
1350
+ this.#selectedElement = data;
1351
+ } else if (data instanceof AiAssistanceModel.NetworkAgent.RequestContext) {
1352
+ this.#selectedRequest = data;
1353
+ } else if (data instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
1354
+ this.#selectedPerformanceTrace = data;
1366
1355
  }
1367
1356
 
1368
1357
  this.#isContextAutoSelectionSuspended = false;
@@ -1463,7 +1452,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1463
1452
  text,
1464
1453
  {
1465
1454
  signal,
1466
- extraContext: this.#additionalContextItemsFromFloaty,
1467
1455
  multimodalInput,
1468
1456
  },
1469
1457
  ),
@@ -1574,6 +1562,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1574
1562
  commitStep();
1575
1563
  break;
1576
1564
  }
1565
+
1577
1566
  case AiAssistanceModel.AiAgent.ResponseType.ANSWER: {
1578
1567
  systemMessage.rpcId = data.rpcId;
1579
1568
  const lastPart = systemMessage.parts.at(-1);
@@ -10,9 +10,6 @@ import type * as Platform from '../../../core/platform/platform.js';
10
10
  import * as SDK from '../../../core/sdk/sdk.js';
11
11
  import * as Protocol from '../../../generated/protocol.js';
12
12
  import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
13
- import * as GreenDev from '../../../models/greendev/greendev.js';
14
- import * as Trace from '../../../models/trace/trace.js';
15
- import * as Workspace from '../../../models/workspace/workspace.js';
16
13
  import * as PanelsCommon from '../../../panels/common/common.js';
17
14
  import * as PanelUtils from '../../../panels/utils/utils.js';
18
15
  import * as Buttons from '../../../ui/components/buttons/buttons.js';
@@ -39,14 +36,6 @@ const UIStrings = {
39
36
  * @description The footer disclaimer that links to more information about the AI feature.
40
37
  */
41
38
  learnAbout: 'Learn about AI in DevTools',
42
- /**
43
- * @description Label added to the button that remove the currently selected context in AI Assistance panel.
44
- */
45
- removeContext: 'Remove from context',
46
- /**
47
- * @description Label added to the button that add selected context from the current panel in AI Assistance panel.
48
- */
49
- addContext: 'Add selected item as context',
50
39
  } as const;
51
40
 
52
41
  /*
@@ -93,6 +82,30 @@ const UIStringsNotTranslate = {
93
82
  * @description Message displayed in toast in case of any failures while uploading an image file as input.
94
83
  */
95
84
  uploadImageFailureMessage: 'Failed to upload image. Please try again.',
85
+ /**
86
+ * @description Label added to the button that add selected context from the current panel in AI Assistance panel.
87
+ */
88
+ addContext: 'Add item for context',
89
+ /**
90
+ * @description Label added to the button that remove the currently selected element in AI Assistance panel.
91
+ */
92
+ removeContextElement: 'Remove element from context',
93
+ /**
94
+ * @description Label added to the button that remove the currently selected context in AI Assistance panel.
95
+ */
96
+ removeContextRequest: 'Remove request from context',
97
+ /**
98
+ * @description Label added to the button that remove the currently selected context in AI Assistance panel.
99
+ */
100
+ removeContextFile: 'Remove file from context',
101
+ /**
102
+ * @description Label added to the button that remove the currently selected context in AI Assistance panel.
103
+ */
104
+ removeContextPerfInsight: 'Remove performance insight from context',
105
+ /**
106
+ * @description Label added to the button that remove the currently selected context in AI Assistance panel.
107
+ */
108
+ removeContext: 'Remove from context',
96
109
  } as const;
97
110
 
98
111
  const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/components/ChatInput.ts', UIStrings);
@@ -123,7 +136,6 @@ export interface ViewInput {
123
136
  inputPlaceholder: Platform.UIString.LocalizedString;
124
137
  selectedContext: AiAssistanceModel.AiAgent.ConversationContext<unknown>|null;
125
138
  inspectElementToggled: boolean;
126
- additionalFloatyContext: UI.Floaty.FloatyContextSelection[];
127
139
  disclaimerText: string;
128
140
  conversationType: AiAssistanceModel.AiHistoryStorage.ConversationType;
129
141
  multimodalInputEnabled: boolean;
@@ -151,22 +163,36 @@ export interface ViewInput {
151
163
 
152
164
  export type ViewOutput = undefined;
153
165
 
154
- export const
155
- DEFAULT_VIEW =
156
- (input: ViewInput, output: ViewOutput, target: HTMLElement):
157
- void => {
158
- const chatInputContainerCls = Lit.Directives.classMap({
159
- 'chat-input-container': true,
160
- 'single-line-layout': !input.selectedContext && !input.onContextAdd,
161
- disabled: input.isTextInputDisabled,
162
- });
163
-
164
- const renderRelevantDataDisclaimer = (tooltipId: string): Lit.LitTemplate => {
165
- const classes = Lit.Directives.classMap({
166
- 'chat-input-disclaimer': true,
167
- 'hide-divider': !input.isLoading && input.blockedByCrossOrigin,
168
- });
169
- // clang-format off
166
+ function getContextRemoveLabel(context: AiAssistanceModel.AiAgent.ConversationContext<unknown>):
167
+ Platform.UIString.LocalizedString {
168
+ if (context instanceof AiAssistanceModel.FileAgent.FileContext) {
169
+ return lockedString(UIStringsNotTranslate.removeContextFile);
170
+ }
171
+ if (context instanceof AiAssistanceModel.StylingAgent.NodeContext) {
172
+ return lockedString(UIStringsNotTranslate.removeContextElement);
173
+ }
174
+ if (context instanceof AiAssistanceModel.NetworkAgent.RequestContext) {
175
+ return lockedString(UIStringsNotTranslate.removeContextRequest);
176
+ }
177
+ if (context instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
178
+ return lockedString(UIStringsNotTranslate.removeContextPerfInsight);
179
+ }
180
+ return lockedString(UIStringsNotTranslate.removeContext);
181
+ }
182
+
183
+ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTMLElement): void => {
184
+ const chatInputContainerCls = Lit.Directives.classMap({
185
+ 'chat-input-container': true,
186
+ 'single-line-layout': !input.selectedContext && !input.onContextAdd,
187
+ disabled: input.isTextInputDisabled,
188
+ });
189
+
190
+ const renderRelevantDataDisclaimer = (tooltipId: string): Lit.LitTemplate => {
191
+ const classes = Lit.Directives.classMap({
192
+ 'chat-input-disclaimer': true,
193
+ 'hide-divider': !input.isLoading && input.blockedByCrossOrigin,
194
+ });
195
+ // clang-format off
170
196
  return html`
171
197
  <div class=${classes}>
172
198
  <button
@@ -198,10 +224,10 @@ export const
198
224
  </div></devtools-tooltip>
199
225
  </div>
200
226
  `;
201
- // clang-format on
202
- };
227
+ // clang-format on
228
+ };
203
229
 
204
- // clang-format off
230
+ // clang-format off
205
231
  Lit.render(html`
206
232
  <style>${Input.textInputStyles}</style>
207
233
  <style>${chatInputStyles}</style>
@@ -226,52 +252,6 @@ export const
226
252
  :
227
253
  html`
228
254
  <form class="input-form" @submit=${input.onSubmit}>
229
- ${GreenDev.Prototypes.instance().isEnabled('inDevToolsFloaty') ?
230
- html`
231
- <ul class="floaty">
232
- ${input.additionalFloatyContext.map(c => {
233
- return html`
234
- <li>
235
- <span class="context-item">
236
- ${c instanceof SDK.NetworkRequest.NetworkRequest ? html`${c.url()}` :
237
- c instanceof SDK.DOMModel.DOMNode ? html`
238
- <devtools-widget .widgetConfig=${
239
- UI.Widget.widgetConfig(PanelsCommon.DOMLinkifier.DOMNodeLink, {node: c})}
240
- ></devtools-widget>` :
241
- 'insight' in c ? html`${c.insight.title}` :
242
- 'event' in c && 'traceStartTime' in c ? html`
243
- ${c.event.name} @ ${i18n.TimeUtilities.formatMicroSecondsAsMillisFixed(Trace.Types.Timing.Micro(c.event.ts - c.traceStartTime))}` :
244
- Lit.nothing}
245
- </span>
246
- <devtools-button
247
- class="floaty-delete-button"
248
- @click=${(e: MouseEvent) => {
249
- e.preventDefault();
250
- UI.Floaty.onFloatyContextDelete(c);
251
- }}
252
- .data=${{
253
- variant: Buttons.Button.Variant.ICON,
254
- iconName: 'cross',
255
- title: 'Delete',
256
- size: Buttons.Button.Size.SMALL,
257
- } as Buttons.Button.ButtonData}
258
- ></devtools-button>
259
- </li>`;
260
- })}
261
- <li class="open-floaty">
262
- <devtools-button
263
- class="floaty-add-button"
264
- @click=${UI.Floaty.onFloatyOpen}
265
- .data=${{
266
- variant: Buttons.Button.Variant.ICON,
267
- iconName: 'select-element',
268
- title: 'Open context picker',
269
- size: Buttons.Button.Size.SMALL,
270
- } as Buttons.Button.ButtonData}
271
- ></devtools-button>
272
- </li>
273
- </ul>`
274
- : Lit.nothing}
275
255
  <div class=${chatInputContainerCls}>
276
256
  ${(input.multimodalInputEnabled && input.imageInput && !input.isTextInputDisabled) ?
277
257
  html`
@@ -355,20 +335,20 @@ export const
355
335
  }}
356
336
  aria-description=${i18nString(UIStrings.revealContextDescription)}
357
337
  >
358
- ${input.selectedContext.getItem() instanceof SDK.NetworkRequest.NetworkRequest ?
359
- PanelUtils.PanelUtils.getIconForNetworkRequest(input.selectedContext.getItem() as SDK.NetworkRequest.NetworkRequest) :
360
- input.selectedContext.getItem() instanceof Workspace.UISourceCode.UISourceCode ?
361
- PanelUtils.PanelUtils.getIconForSourceFile(input.selectedContext.getItem() as Workspace.UISourceCode.UISourceCode) :
362
- input.selectedContext.getItem() instanceof AiAssistanceModel.AIContext.AgentFocus ?
338
+ ${input.selectedContext instanceof AiAssistanceModel.NetworkAgent.RequestContext ?
339
+ PanelUtils.PanelUtils.getIconForNetworkRequest(input.selectedContext.getItem()) :
340
+ input.selectedContext instanceof AiAssistanceModel.FileAgent.FileContext ?
341
+ PanelUtils.PanelUtils.getIconForSourceFile(input.selectedContext.getItem()) :
342
+ input.selectedContext instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext ?
363
343
  html`<devtools-icon name="performance" title="Performance"></devtools-icon>` :
364
344
  Lit.nothing}
365
345
  <span class="title">
366
- ${input.selectedContext.getItem() instanceof SDK.DOMModel.DOMNode ?
346
+ ${input.selectedContext instanceof AiAssistanceModel.StylingAgent.NodeContext ?
367
347
  html`
368
348
  <devtools-widget .widgetConfig=${UI.Widget.widgetConfig(PanelsCommon.DOMLinkifier.DOMNodeLink, {
369
- node: input.selectedContext.getItem() as SDK.DOMModel.DOMNode,
349
+ node: input.selectedContext.getItem(),
370
350
  options: {
371
- hiddenClassList: (input.selectedContext.getItem() as SDK.DOMModel.DOMNode).classNames().filter(
351
+ hiddenClassList: input.selectedContext.getItem().classNames().filter(
372
352
  className => className.startsWith(AiAssistanceModel.Injected.AI_ASSISTANCE_CSS_CLASS_NAME)),
373
353
  disabled: input.isTextInputDisabled,
374
354
  },
@@ -378,8 +358,8 @@ export const
378
358
  </span>
379
359
  ${input.onContextRemoved ? html`
380
360
  <devtools-button
381
- title=${i18nString(UIStrings.removeContext)}
382
- aria-label=${i18nString(UIStrings.removeContext)}
361
+ title=${getContextRemoveLabel(input.selectedContext)}
362
+ aria-label=${getContextRemoveLabel(input.selectedContext)}
383
363
  class="remove-context"
384
364
  .iconName=${'cross'}
385
365
  .size=${Buttons.Button.Size.MICRO}
@@ -391,8 +371,8 @@ export const
391
371
  :
392
372
  input.onContextAdd ? html`
393
373
  <devtools-button
394
- title=${i18nString(UIStrings.addContext)}
395
- aria-label=${i18nString(UIStrings.addContext)}
374
+ title=${lockedString(UIStringsNotTranslate.addContext)}
375
+ aria-label=${lockedString(UIStringsNotTranslate.addContext)}
396
376
  class="add-context"
397
377
  .iconName=${'plus'}
398
378
  .size=${Buttons.Button.Size.SMALL}
@@ -494,9 +474,9 @@ export const
494
474
  >
495
475
  ${renderRelevantDataDisclaimer(RELEVANT_DATA_LINK_FOOTER_ID)}
496
476
  </footer>
497
- `, target);
498
- // clang-format on
499
- };
477
+ `, target,);
478
+ // clang-format on
479
+ };
500
480
 
501
481
  /**
502
482
  * ChatInput is a presenter for the input area in the AI Assistance panel.
@@ -506,9 +486,8 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
506
486
  blockedByCrossOrigin = false;
507
487
  isTextInputDisabled = false;
508
488
  inputPlaceholder = '' as Platform.UIString.LocalizedString;
509
- selectedContext = null as AiAssistanceModel.AiAgent.ConversationContext<unknown>| null;
489
+ selectedContext: AiAssistanceModel.AiAgent.ConversationContext<unknown>|null = null;
510
490
  inspectElementToggled = false;
511
- additionalFloatyContext = [] as UI.Floaty.FloatyContextSelection[];
512
491
  disclaimerText = '';
513
492
  conversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING;
514
493
  multimodalInputEnabled = false;
@@ -697,7 +676,6 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
697
676
  selectedContext: this.selectedContext,
698
677
  inspectElementToggled: this.inspectElementToggled,
699
678
  isTextInputEmpty: this.#isTextInputEmpty(),
700
- additionalFloatyContext: this.additionalFloatyContext,
701
679
  disclaimerText: this.disclaimerText,
702
680
  conversationType: this.conversationType,
703
681
  multimodalInputEnabled: this.multimodalInputEnabled,
@@ -221,6 +221,7 @@ export interface RatingViewInput {
221
221
  export interface ActionViewInput {
222
222
  onReportClick: () => void;
223
223
  onCopyResponseClick: () => void;
224
+ showActions: boolean;
224
225
  }
225
226
 
226
227
  export interface SuggestionViewInput {
@@ -330,7 +331,7 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
330
331
  },
331
332
  )}
332
333
  ${renderError(message)}
333
- ${input.isLastMessage && !input.isLoading ? renderActions(input, output) : Lit.nothing}
334
+ ${input.showActions ? renderActions(input, output) : Lit.nothing}
334
335
  </section>
335
336
  `, target);
336
337
  // clang-format on
@@ -812,8 +813,9 @@ export class ChatMessage extends UI.Widget.Widget {
812
813
  onInputChange: this.#handleInputChange.bind(this),
813
814
  isSubmitButtonDisabled: this.#isSubmitButtonDisabled,
814
815
  // Props for actions logic
816
+ showActions: !(this.isLastMessage && this.isLoading),
815
817
  showRateButtons: this.message.entity === ChatMessageEntity.MODEL && !!this.message.rpcId,
816
- suggestions: (this.message.entity === ChatMessageEntity.MODEL && !this.isReadOnly &&
818
+ suggestions: (this.isLastMessage && this.message.entity === ChatMessageEntity.MODEL && !this.isReadOnly &&
817
819
  this.message.parts.at(-1)?.type === 'answer') ?
818
820
  (this.message.parts.at(-1) as AnswerPart).suggestions :
819
821
  undefined,
@@ -76,7 +76,6 @@ export interface Props {
76
76
  disclaimerText: Platform.UIString.LocalizedString;
77
77
  uploadImageInputEnabled?: boolean;
78
78
  markdownRenderer: MarkdownLitRenderer;
79
- additionalFloatyContext: UI.Floaty.FloatyContextSelection[];
80
79
  }
81
80
 
82
81
  interface ChatWidgetInput extends Props {
@@ -171,7 +170,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
171
170
  conversationType: input.conversationType,
172
171
  uploadImageInputEnabled: input.uploadImageInputEnabled ?? false,
173
172
  isReadOnly: input.isReadOnly,
174
- additionalFloatyContext: input.additionalFloatyContext,
175
173
  onContextClick: input.onContextClick,
176
174
  onInspectElementClick: input.onInspectElementClick,
177
175
  onTextSubmit: input.onTextSubmit,
@@ -228,14 +228,12 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: ViewOutput, target: HTMLE
228
228
  <div class="top-left-corner">
229
229
  <devtools-checkbox
230
230
  ${bindToSetting(input.showTestAddressesInAutofillMenuSetting)}
231
- title=${i18nString(UIStrings.showTestAddressesInAutofillMenu)}
232
- jslog=${VisualLogging.toggle(input.showTestAddressesInAutofillMenuSetting.name).track({ change: true })}>
231
+ title=${i18nString(UIStrings.showTestAddressesInAutofillMenu)}>
233
232
  ${i18nString(UIStrings.showTestAddressesInAutofillMenu)}
234
233
  </devtools-checkbox>
235
234
  <devtools-checkbox
236
235
  ${bindToSetting(input.autoOpenViewSetting)}
237
- title=${i18nString(UIStrings.autoShowTooltip)}
238
- jslog=${VisualLogging.toggle(input.autoOpenViewSetting.name).track({ change: true })}>
236
+ title=${i18nString(UIStrings.autoShowTooltip)}>
239
237
  ${i18nString(UIStrings.autoShow)}
240
238
  </devtools-checkbox>
241
239
  <devtools-link href=${AUTOFILL_FEEDBACK_URL} class="feedback link" jslogcontext="feedback">${i18nString(UIStrings.sendFeedback)}</devtools-link>
@@ -267,16 +265,14 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: ViewOutput, target: HTMLE
267
265
  <div class="label-container">
268
266
  <devtools-checkbox
269
267
  ${bindToSetting(input.showTestAddressesInAutofillMenuSetting)}
270
- title=${i18nString(UIStrings.showTestAddressesInAutofillMenu)}
271
- jslog=${VisualLogging.toggle(input.showTestAddressesInAutofillMenuSetting.name).track({ change: true })}>
268
+ title=${i18nString(UIStrings.showTestAddressesInAutofillMenu)}>
272
269
  ${i18nString(UIStrings.showTestAddressesInAutofillMenu)}
273
270
  </devtools-checkbox>
274
271
  </div>
275
272
  <div class="label-container">
276
273
  <devtools-checkbox
277
274
  ${bindToSetting(input.autoOpenViewSetting)}
278
- title=${i18nString(UIStrings.autoShowTooltip)}
279
- jslog=${VisualLogging.toggle(input.autoOpenViewSetting.name).track({ change: true })}>
275
+ title=${i18nString(UIStrings.autoShowTooltip)}>
280
276
  ${i18nString(UIStrings.autoShow)}
281
277
  </devtools-checkbox>
282
278
  </div>
@@ -23,6 +23,14 @@ const UIStringsNotTranslate = {
23
23
  * @description Text for teaser to generate code in Mac.
24
24
  */
25
25
  cmdItoGenerateCode: 'cmd+i to generate code',
26
+ /**
27
+ * @description Text for teaser to learn how data is being used.
28
+ */
29
+ ctrlOneTimeDisclaimerToLearnHowYourDataIsBeingUsed: 'ctrl+. to learn how your data is being used.',
30
+ /**
31
+ * @description Text for teaser to learn how data is being used in Mac.
32
+ */
33
+ cmdOneTimeDisclaimerToLearnHowYourDataIsBeingUsed: 'cmd+. to learn how your data is being used.',
26
34
  /**
27
35
  * @description Aria label for teaser to generate code.
28
36
  */
@@ -47,6 +55,14 @@ const UIStringsNotTranslate = {
47
55
  * @description Text for teaser when suggestion has been generated.
48
56
  */
49
57
  tab: 'tab',
58
+ /**
59
+ * @description Text for teaser when suggestion has been generated.
60
+ */
61
+ or: 'or',
62
+ /**
63
+ * @description Text for teaser when suggestion has been generated.
64
+ */
65
+ enter: 'enter',
50
66
  /**
51
67
  * @description Text for teaser when suggestion has been generated.
52
68
  */
@@ -109,6 +125,7 @@ export interface ViewInput {
109
125
  disclaimerTooltipId?: string;
110
126
  noLogging: boolean;
111
127
  onManageInSettingsTooltipClick: (event: Event) => void;
128
+ showDataUsageTeaser: boolean;
112
129
  // TODO(b/472268298): Remove ContextFlavor explicitly and pass required values
113
130
  panel?: AiCodeCompletion.AiCodeCompletion.ContextFlavor;
114
131
  }
@@ -136,18 +153,23 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
136
153
  }
137
154
  const toGenerateCode = Host.Platform.isMac() ? lockedString(UIStringsNotTranslate.cmdItoGenerateCode) :
138
155
  lockedString(UIStringsNotTranslate.ctrlItoGenerateCode);
139
- const toLearnHowYourDataIsBeingUsed = Host.Platform.isMac() ?
156
+ const toLearnHowYourDataIsBeingUsedScreenReaderOnly = Host.Platform.isMac() ?
140
157
  lockedString(UIStringsNotTranslate.pressCmdPeriodToLearnHowYourDataIsBeingUsed) :
141
158
  lockedString(UIStringsNotTranslate.pressCtrlPeriodToLearnHowYourDataIsBeingUsed);
159
+ const toLearnHowYourDataIsBeingUsedVisible = Host.Platform.isMac() ?
160
+ lockedString(UIStringsNotTranslate.cmdOneTimeDisclaimerToLearnHowYourDataIsBeingUsed) :
161
+ lockedString(UIStringsNotTranslate.ctrlOneTimeDisclaimerToLearnHowYourDataIsBeingUsed);
142
162
  const tooltipDisclaimerText = getTooltipDisclaimerText(input.noLogging, input.panel);
143
- // TODO(b/472291834): Disclaimer icon should match the placeholder's color
163
+
144
164
  // clang-format off
145
165
  teaserLabel = html`<div class="ai-code-generation-teaser-trigger">
146
- <span aria-atomic="true" aria-live="assertive">${toGenerateCode}&nbsp;</span>
147
- <div class="ai-code-generation-teaser-screen-reader-only" aria-atomic="true" aria-live="assertive">
148
- ${toLearnHowYourDataIsBeingUsed}
149
- </div>
150
- <devtools-button
166
+ <span aria-atomic="true" aria-live="assertive">${toGenerateCode}</span>
167
+ ${input.showDataUsageTeaser ?
168
+ html`<span aria-hidden="true">${'. ' + toLearnHowYourDataIsBeingUsedVisible}</span>` : nothing}
169
+ <span class="ai-code-generation-teaser-screen-reader-only" aria-atomic="true" aria-live="assertive">
170
+ ${toLearnHowYourDataIsBeingUsedScreenReaderOnly}
171
+ </span>
172
+ &nbsp;<devtools-button
151
173
  .data=${{
152
174
  title: lockedString(UIStringsNotTranslate.learnMoreAboutHowYourDataIsBeingUsed),
153
175
  size: Buttons.Button.Size.MICRO,
@@ -220,6 +242,8 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
220
242
  // clang-format off
221
243
  teaserLabel = html`<div class="ai-code-generation-teaser-generated">
222
244
  <span>${lockedString(UIStringsNotTranslate.tab)}</span>
245
+ &nbsp;${lockedString(UIStringsNotTranslate.or)}&nbsp;
246
+ <span>${lockedString(UIStringsNotTranslate.enter)}</span>
223
247
  &nbsp;${lockedString(UIStringsNotTranslate.toAccept)}
224
248
  </div>`;
225
249
  // clang-format on
@@ -245,12 +269,13 @@ export class AiCodeGenerationTeaser extends UI.Widget.Widget {
245
269
  readonly #view: View;
246
270
  #viewOutput: ViewOutput = {};
247
271
 
248
- #displayState = AiCodeGenerationTeaserDisplayState.TRIGGER;
272
+ #displayState = AiCodeGenerationTeaserDisplayState.DISCOVERY;
249
273
  #disclaimerTooltipId?: string;
250
274
  #noLogging: boolean; // Whether the enterprise setting is `ALLOW_WITHOUT_LOGGING` or not.
251
275
  #panel?: AiCodeCompletion.AiCodeCompletion.ContextFlavor;
252
276
  #timerIntervalId?: number;
253
277
  #loadStartTime?: number;
278
+ static #showDataUsageTeaser = true;
254
279
 
255
280
  constructor(view?: View) {
256
281
  super();
@@ -268,6 +293,7 @@ export class AiCodeGenerationTeaser extends UI.Widget.Widget {
268
293
  onManageInSettingsTooltipClick: this.#onManageInSettingsTooltipClick.bind(this),
269
294
  disclaimerTooltipId: this.#disclaimerTooltipId,
270
295
  noLogging: this.#noLogging,
296
+ showDataUsageTeaser: AiCodeGenerationTeaser.#showDataUsageTeaser,
271
297
  panel: this.#panel,
272
298
  },
273
299
  this.#viewOutput, this.contentElement);
@@ -286,6 +312,9 @@ export class AiCodeGenerationTeaser extends UI.Widget.Widget {
286
312
  if (displayState === this.#displayState) {
287
313
  return;
288
314
  }
315
+ if (this.#displayState === AiCodeGenerationTeaserDisplayState.TRIGGER) {
316
+ AiCodeGenerationTeaser.#showDataUsageTeaser = false;
317
+ }
289
318
  this.#displayState = displayState;
290
319
  this.requestUpdate();
291
320
  if (this.#displayState === AiCodeGenerationTeaserDisplayState.LOADING) {
@@ -72,7 +72,6 @@ import {
72
72
  ConsoleTableMessageView,
73
73
  ConsoleViewMessage,
74
74
  getMessageForElement,
75
- MaxLengthForLinks,
76
75
  } from './ConsoleViewMessage.js';
77
76
  import {ConsoleViewport, type ConsoleViewportElement, type ConsoleViewportProvider} from './ConsoleViewport.js';
78
77
 
@@ -549,7 +548,7 @@ export class ConsoleView extends UI.Widget.VBox implements
549
548
  // the linkifiers live location change event.
550
549
  const throttler = new Common.Throttler.Throttler(100);
551
550
  const refilterMessages = (): Promise<void> => throttler.schedule(async () => this.onFilterChanged());
552
- this.linkifier = new Components.Linkifier.Linkifier(MaxLengthForLinks);
551
+ this.linkifier = new Components.Linkifier.Linkifier(UI.UIUtils.MaxLengthForDisplayedURLsInConsole);
553
552
  this.linkifier.addEventListener(Components.Linkifier.Events.LIVE_LOCATION_UPDATED, refilterMessages);
554
553
 
555
554
  this.consoleMessages = [];