chrome-devtools-frontend 1.0.1598808 → 1.0.1601661

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 (161) hide show
  1. package/.agents/README.md +13 -0
  2. package/{agents/prompts/creating-a-model.md → .agents/skills/creating-a-model/SKILL.md} +7 -1
  3. package/{agents/prompts/devtools-imports.md → .agents/skills/devtools-imports/SKILL.md} +10 -5
  4. package/{agents/prompts/merging-devtools-module.md → .agents/skills/merging-devtools-module/SKILL.md} +5 -0
  5. package/{agents/prompts/ui-widgets.md → .agents/skills/ui-widgets/SKILL.md} +5 -0
  6. package/{agents/prompts/verification.md → .agents/skills/verification/SKILL.md} +5 -0
  7. package/front_end/core/common/Settings.ts +24 -1
  8. package/front_end/core/dom_extension/DOMExtension.ts +1 -0
  9. package/front_end/core/host/AidaClient.ts +5 -2
  10. package/front_end/core/host/AidaGcaTranslation.ts +377 -0
  11. package/front_end/core/host/GcaTypes.ts +520 -0
  12. package/front_end/core/host/UserMetrics.ts +0 -3
  13. package/front_end/core/host/host.ts +4 -0
  14. package/front_end/core/root/ExperimentNames.ts +0 -3
  15. package/front_end/core/sdk/CPUThrottlingManager.ts +12 -9
  16. package/front_end/core/sdk/ResourceTreeModel.ts +1 -1
  17. package/front_end/core/sdk/SourceMap.ts +4 -2
  18. package/front_end/entrypoints/main/MainImpl.ts +1 -12
  19. package/front_end/generated/Deprecation.ts +16 -0
  20. package/front_end/generated/InspectorBackendCommands.ts +4 -6
  21. package/front_end/generated/protocol.ts +46 -77
  22. package/front_end/models/ai_assistance/AiConversation.ts +49 -22
  23. package/front_end/models/ai_assistance/AiHistoryStorage.snapshot.txt +1 -1
  24. package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -0
  25. package/front_end/models/ai_assistance/ConversationHandler.ts +16 -11
  26. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +76 -36
  27. package/front_end/models/ai_assistance/agents/AiAgent.ts +26 -2
  28. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +0 -1
  29. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +11 -0
  30. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +39 -0
  31. package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +53 -12
  32. package/front_end/models/ai_assistance/agents/FileAgent.ts +0 -15
  33. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +0 -5
  34. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +57 -0
  35. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +87 -15
  36. package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +0 -10
  37. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -6
  38. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -5
  39. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  40. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +84 -0
  41. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +172 -0
  42. package/front_end/models/breakpoints/BreakpointManager.ts +20 -12
  43. package/front_end/models/emulation/DeviceModeModel.ts +5 -1
  44. package/front_end/models/emulation/EmulatedDevices.ts +3 -2
  45. package/front_end/models/javascript_metadata/NativeFunctions.js +60 -0
  46. package/front_end/models/lighthouse/LighthouseReporterTypes.ts +104 -10
  47. package/front_end/models/lighthouse/RunTypes.ts +42 -0
  48. package/front_end/models/lighthouse/lighthouse.ts +2 -0
  49. package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +59 -35
  50. package/front_end/models/stack_trace/StackTrace.ts +5 -0
  51. package/front_end/models/stack_trace/StackTraceImpl.ts +7 -1
  52. package/front_end/models/stack_trace/StackTraceModel.ts +2 -1
  53. package/front_end/models/stack_trace/stack_trace.ts +4 -0
  54. package/front_end/models/trace/ModelImpl.ts +4 -0
  55. package/front_end/models/trace/helpers/SamplesIntegrator.ts +1 -8
  56. package/front_end/models/trace/types/Configuration.ts +0 -5
  57. package/front_end/panels/accessibility/AccessibilityNodeView.ts +7 -3
  58. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +163 -74
  59. package/front_end/panels/ai_assistance/ExportConversation.ts +25 -0
  60. package/front_end/panels/ai_assistance/ai_assistance.ts +2 -0
  61. package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -0
  62. package/front_end/panels/ai_assistance/components/ChatMessage.ts +120 -32
  63. package/front_end/panels/ai_assistance/components/ChatView.ts +44 -0
  64. package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +240 -0
  65. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +4 -12
  66. package/front_end/panels/ai_assistance/components/StylingAgentMarkdownRenderer.ts +5 -27
  67. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +115 -17
  68. package/front_end/panels/ai_assistance/components/chatMessage.css +65 -1
  69. package/front_end/panels/ai_assistance/components/chatView.css +8 -0
  70. package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +82 -0
  71. package/front_end/panels/ai_assistance/components/walkthroughView.css +9 -1
  72. package/front_end/panels/animation/AnimationTimeline.ts +5 -5
  73. package/front_end/panels/application/AppManifestView.ts +13 -7
  74. package/front_end/panels/application/FrameDetailsView.ts +4 -4
  75. package/front_end/panels/application/preloading/PreloadingView.ts +2 -4
  76. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +6 -3
  77. package/front_end/panels/application/preloading/components/PreloadingString.ts +15 -2
  78. package/front_end/panels/application/preloading/helper/PreloadingForward.ts +31 -2
  79. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +3 -2
  80. package/front_end/panels/common/DOMLinkifier.ts +10 -8
  81. package/front_end/panels/console/ConsoleView.ts +24 -2
  82. package/front_end/panels/console/ConsoleViewMessage.ts +22 -23
  83. package/front_end/panels/console/console.ts +0 -2
  84. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +5 -5
  85. package/front_end/panels/elements/ElementsTreeElement.ts +2 -3
  86. package/front_end/panels/elements/PropertiesWidget.ts +5 -3
  87. package/front_end/panels/elements/StandaloneStylesContainer.ts +21 -9
  88. package/front_end/panels/elements/StylePropertiesSection.ts +98 -50
  89. package/front_end/panels/elements/StylePropertyTreeElement.ts +38 -4
  90. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +43 -35
  91. package/front_end/panels/elements/StylesSidebarPane.ts +154 -24
  92. package/front_end/panels/elements/components/ComputedStyleTrace.ts +3 -2
  93. package/front_end/panels/event_listeners/EventListenersView.ts +16 -4
  94. package/front_end/panels/explain/components/ConsoleInsight.ts +6 -9
  95. package/front_end/panels/explain/explain-meta.ts +5 -0
  96. package/front_end/panels/issues/AffectedResourcesView.ts +5 -9
  97. package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +1 -1
  98. package/front_end/panels/lighthouse/LighthouseController.ts +154 -164
  99. package/front_end/panels/lighthouse/LighthousePanel.ts +5 -9
  100. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +1 -0
  101. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +9 -6
  102. package/front_end/panels/lighthouse/LighthouseStartView.ts +7 -6
  103. package/front_end/panels/lighthouse/LighthouseStatusView.ts +32 -8
  104. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +7 -3
  105. package/front_end/panels/network/NetworkDataGridNode.ts +34 -0
  106. package/front_end/panels/network/NetworkLogViewColumns.ts +10 -0
  107. package/front_end/panels/network/RequestPayloadView.ts +4 -1
  108. package/front_end/panels/network/RequestTimingView.ts +8 -2
  109. package/front_end/panels/performance_monitor/performanceMonitor.css +6 -4
  110. package/front_end/panels/recorder/RecorderController.ts +52 -14
  111. package/front_end/panels/recorder/components/RecordingView.ts +2 -1
  112. package/front_end/panels/recorder/models/RecordingStorage.ts +15 -20
  113. package/front_end/panels/sensors/SensorsView.ts +333 -157
  114. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +18 -4
  115. package/front_end/panels/sources/DebuggerPausedMessage.ts +6 -6
  116. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -3
  117. package/front_end/panels/sources/NavigatorView.ts +11 -7
  118. package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
  119. package/front_end/panels/sources/SourcesPanel.ts +12 -34
  120. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +5 -1
  121. package/front_end/panels/sources/sources-meta.ts +6 -0
  122. package/front_end/panels/timeline/StatusDialog.ts +159 -83
  123. package/front_end/panels/timeline/ThirdPartyTreeView.ts +6 -2
  124. package/front_end/panels/timeline/TimelineController.ts +0 -4
  125. package/front_end/panels/timeline/TimelineDetailsView.ts +35 -3
  126. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +6 -1
  127. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +9 -4
  128. package/front_end/panels/timeline/TimelinePanel.ts +36 -11
  129. package/front_end/panels/timeline/TimelineTreeView.ts +14 -3
  130. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -57
  131. package/front_end/panels/timeline/components/InteractionBreakdown.ts +2 -1
  132. package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
  133. package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +3 -7
  134. package/front_end/panels/timeline/components/Sidebar.ts +11 -19
  135. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +2 -1
  136. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +60 -27
  137. package/front_end/panels/timeline/components/TimelineRangeSummaryView.ts +66 -0
  138. package/front_end/panels/timeline/components/TimelineSummary.ts +7 -19
  139. package/front_end/panels/timeline/components/components.ts +2 -0
  140. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +55 -28
  141. package/front_end/panels/timeline/components/insights/NodeLink.ts +3 -3
  142. package/front_end/panels/timeline/components/insights/baseInsightComponent.css +7 -0
  143. package/front_end/panels/timeline/components/insights/insights.ts +0 -2
  144. package/front_end/panels/timeline/components/timelineRangeSummaryView.css +20 -0
  145. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +7 -7
  146. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  147. package/front_end/panels/timeline/timelineDetailsView.css +0 -9
  148. package/front_end/third_party/chromium/README.chromium +1 -1
  149. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +11 -2
  150. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +11 -2
  151. package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +65 -4
  152. package/front_end/ui/kit/link/link.css +2 -2
  153. package/front_end/ui/legacy/Widget.ts +5 -3
  154. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +7 -2
  155. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +57 -35
  156. package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +1 -0
  157. package/front_end/ui/visual_logging/KnownContextValues.ts +6 -1
  158. package/package.json +1 -1
  159. package/agents/prompts/README.md +0 -18
  160. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +0 -93
  161. /package/front_end/{panels/console → models/stack_trace}/ErrorStackParser.ts +0 -0
@@ -14,7 +14,7 @@ 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
16
  import * as Greendev from '../../models/greendev/greendev.js';
17
- import * as TextUtils from '../../models/text_utils/text_utils.js';
17
+ import type * as LHModel from '../../models/lighthouse/lighthouse.js';
18
18
  import type * as Trace from '../../models/trace/trace.js';
19
19
  import * as Workspace from '../../models/workspace/workspace.js';
20
20
  import * as Buttons from '../../ui/components/buttons/buttons.js';
@@ -23,6 +23,7 @@ import * as UIHelpers from '../../ui/helpers/helpers.js';
23
23
  import * as UI from '../../ui/legacy/legacy.js';
24
24
  import * as Lit from '../../ui/lit/lit.js';
25
25
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
26
+ import * as LighthousePanel from '../lighthouse/lighthouse.js';
26
27
  import * as NetworkForward from '../network/forward/forward.js';
27
28
  import * as NetworkPanel from '../network/network.js';
28
29
  import * as TimelinePanel from '../timeline/timeline.js';
@@ -47,6 +48,7 @@ import {StylingAgentMarkdownRenderer} from './components/StylingAgentMarkdownRen
47
48
  import {
48
49
  WalkthroughView,
49
50
  } from './components/WalkthroughView.js';
51
+ import {saveToDisk} from './ExportConversation.js';
50
52
  import {isAiAssistancePatchingEnabled} from './PatchWidget.js';
51
53
 
52
54
  const {html} = Lit;
@@ -129,6 +131,10 @@ const UIStringsNotTranslate = {
129
131
  * @description Announcement text for screen readers when the answer comes.
130
132
  */
131
133
  answerReady: 'Answer ready',
134
+ /**
135
+ * @description Title for the first step of the walkthrough.
136
+ */
137
+ analyzingData: 'Analyzing data',
132
138
  /**
133
139
  * @description Placeholder text for the input shown when the conversation is blocked because a cross-origin context was selected.
134
140
  */
@@ -227,6 +233,24 @@ const UIStringsNotTranslate = {
227
233
  */
228
234
  inputDisclaimerForNoContextEnterpriseNoLogging:
229
235
  'Chat messages, any data the inspected page can see using Web APIs, and the items you select such as files, network requests, and performance traces are sent to Google. This data will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
236
+ /**
237
+ * @description Placeholder text for the chat UI input.
238
+ */
239
+ inputPlaceholderForAccessibility: 'Ask a question about the selected Lighthouse report',
240
+ /**
241
+ * @description Placeholder text for the chat UI input when there is no context selected.
242
+ */
243
+ inputPlaceholderForAccessibilityNoContext: 'Generate a Lighthouse report to ask a question',
244
+ /**
245
+ * @description Disclaimer text right after the chat input.
246
+ */
247
+ inputDisclaimerForAccessibility:
248
+ 'Chat messages and the selected Lighthouse report 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.',
249
+ /**
250
+ * @description Disclaimer text right after the chat input.
251
+ */
252
+ inputDisclaimerForAccessibilityEnterpriseNoLogging:
253
+ '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.',
230
254
  } as const;
231
255
 
232
256
  const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/AiAssistancePanel.ts', UIStrings);
@@ -279,7 +303,14 @@ async function getEmptyStateSuggestions(conversation?: AiAssistanceModel.AiConve
279
303
  {title: 'Is the script optimized for performance?', jslogContext: 'file-default'},
280
304
  {title: 'Does the script handle user input safely?', jslogContext: 'file-default'},
281
305
  ];
306
+ case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
307
+ return [
308
+ {title: 'What are the accessibility issues on this page?', jslogContext: 'accessibility-default'},
309
+ {title: 'How can I fix these accessibility issues?', jslogContext: 'accessibility-default'},
310
+ {title: 'What does this Lighthouse report say about accessibility?', jslogContext: 'accessibility-default'},
311
+ ];
282
312
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK:
313
+
283
314
  return [
284
315
  {title: 'Why is this network request taking so long?', jslogContext: 'network-default'},
285
316
  {title: 'Are there any security headers present?', jslogContext: 'network-default'},
@@ -380,6 +411,7 @@ export interface PanelViewOutput {
380
411
  type View = (input: ViewInput, output: PanelViewOutput, target: HTMLElement) => void;
381
412
 
382
413
  function toolbarView(input: ToolbarViewInput): Lit.LitTemplate {
414
+ const hasAiV2 = Boolean(Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled);
383
415
  // clang-format off
384
416
  return html`
385
417
  <div class="toolbar-container" role="toolbar" jslog=${VisualLogging.toolbar()}>
@@ -410,16 +442,18 @@ function toolbarView(input: ToolbarViewInput): Lit.LitTemplate {
410
442
  .variant=${Buttons.Button.Variant.TOOLBAR}
411
443
  @click=${input.onDeleteClick}>
412
444
  </devtools-button>
413
- <devtools-button
414
- title=${i18nString(UIStrings.exportConversation)}
415
- aria-label=${i18nString(UIStrings.exportConversation)}
416
- .iconName=${'download'}
417
- .disabled=${input.isLoading}
418
- .jslogContext=${'export-ai-conversation'}
419
- .variant=${Buttons.Button.Variant.TOOLBAR}
420
- @click=${input.onExportConversationClick}>
421
- </devtools-button>`
422
- : Lit.nothing}
445
+ ${hasAiV2 ? Lit.nothing : html`
446
+ <devtools-button
447
+ title=${i18nString(UIStrings.exportConversation)}
448
+ aria-label=${i18nString(UIStrings.exportConversation)}
449
+ .iconName=${'download'}
450
+ .disabled=${input.isLoading}
451
+ .jslogContext=${'export-ai-conversation'}
452
+ .variant=${Buttons.Button.Variant.TOOLBAR}
453
+ @click=${input.onExportConversationClick}>
454
+ </devtools-button>
455
+ `
456
+ }` : Lit.nothing}
423
457
  </devtools-toolbar>
424
458
  <devtools-toolbar class="freestyler-right-toolbar" role="presentation">
425
459
  <devtools-link
@@ -549,6 +583,14 @@ function createBreakpointContext(uiLocation: Workspace.UISourceCode.UILocation|n
549
583
  return new AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext(uiLocation);
550
584
  }
551
585
 
586
+ function createAccessibilityContext(report: LighthousePanel.LighthousePanel.ActiveLighthouseReport|null):
587
+ AiAssistanceModel.AccessibilityAgent.AccessibilityContext|null {
588
+ if (!report) {
589
+ return null;
590
+ }
591
+ return new AiAssistanceModel.AccessibilityAgent.AccessibilityContext(report.report);
592
+ }
593
+
552
594
  function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|null):
553
595
  AiAssistanceModel.NetworkAgent.RequestContext|null {
554
596
  if (!request) {
@@ -597,6 +639,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
597
639
  // NodeJS debugging does not have Elements panel, thus this action might not exist.
598
640
  #toggleSearchElementAction?: UI.ActionRegistration.Action;
599
641
  #aidaClient: Host.AidaClient.AidaClient;
642
+ #conversationSummaryAgent?: AiAssistanceModel.ConversationSummaryAgent.ConversationSummaryAgent;
600
643
  #viewOutput: PanelViewOutput = {};
601
644
  #serverSideLoggingEnabled = isAiAssistanceServerSideLoggingEnabled();
602
645
  #aiAssistanceEnabledSetting: Common.Settings.Setting<boolean>|undefined;
@@ -610,7 +653,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
610
653
  #selectedPerformanceTrace: AiAssistanceModel.PerformanceAgent.PerformanceTraceContext|null = null;
611
654
  #selectedRequest: AiAssistanceModel.NetworkAgent.RequestContext|null = null;
612
655
  #selectedBreakpoint: AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext|null = null;
656
+ #selectedAccessibility: AiAssistanceModel.AccessibilityAgent.AccessibilityContext|null = null;
613
657
  // Messages displayed in the `ChatView` component.
658
+
614
659
  #messages: Message[] = [];
615
660
 
616
661
  // Whether the UI should show loading or not.
@@ -716,11 +761,23 @@ export class AiAssistancePanel extends UI.Panel.Panel {
716
761
  emptyStateSuggestions,
717
762
  inputPlaceholder: this.#getChatInputPlaceholder(),
718
763
  disclaimerText: this.#getDisclaimerText(),
764
+ onExportConversation: this.#onExportConversationClick.bind(this),
719
765
  changeManager: this.#changeManager,
720
766
  uploadImageInputEnabled: isAiAssistanceMultimodalUploadInputEnabled() &&
721
767
  this.#conversation.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
722
768
  markdownRenderer,
769
+ conversationMarkdown: this.#conversation.getConversationMarkdown(),
770
+ generateConversationSummary: async (markdown: string) => {
771
+ if (!this.#conversationSummaryAgent) {
772
+ this.#conversationSummaryAgent = new AiAssistanceModel.ConversationSummaryAgent.ConversationSummaryAgent({
773
+ aidaClient: this.#aidaClient,
774
+ serverSideLoggingEnabled: this.#serverSideLoggingEnabled,
775
+ });
776
+ }
777
+ return await this.#conversationSummaryAgent.summarizeConversation(markdown);
778
+ },
723
779
  onTextSubmit: async (
780
+
724
781
  text: string, imageInput?: Host.AidaClient.Part,
725
782
  multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
726
783
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
@@ -831,6 +888,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
831
888
  return await TimelinePanel.TimelinePanel.TimelinePanel.executeRecordAndReload();
832
889
  }
833
890
 
891
+ async #handleLighthouseRun(): Promise<LHModel.ReporterTypes.ReportJSON|null> {
892
+ return await LighthousePanel.LighthousePanel.LighthousePanel.executeLighthouseRecording({isAIControlled: true});
893
+ }
894
+
834
895
  #getDefaultConversationType(): AiAssistanceModel.AiHistoryStorage.ConversationType|undefined {
835
896
  const {hostConfig} = Root.Runtime;
836
897
  const viewManager = UI.ViewManager.ViewManager.instance();
@@ -838,6 +899,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
838
899
  const isNetworkPanelVisible = viewManager.isViewVisible('network');
839
900
  const isSourcesPanelVisible = viewManager.isViewVisible('sources');
840
901
  const isPerformancePanelVisible = viewManager.isViewVisible('timeline');
902
+ const isLighthousePanelVisible = viewManager.isViewVisible('lighthouse');
841
903
 
842
904
  let targetConversationType: AiAssistanceModel.AiHistoryStorage.ConversationType|undefined;
843
905
  if (isElementsPanelVisible && hostConfig.devToolsFreestyler?.enabled) {
@@ -852,6 +914,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
852
914
  targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.FILE;
853
915
  } else if (isPerformancePanelVisible && hostConfig.devToolsAiAssistancePerformanceAgent?.enabled) {
854
916
  targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE;
917
+ } else if (isLighthousePanelVisible && hostConfig.devToolsAiAssistanceAccessibilityAgent?.enabled) {
918
+ targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY;
855
919
  }
856
920
 
857
921
  if (isAiAssistanceContextSelectionAgentEnabled() && !targetConversationType) {
@@ -884,12 +948,19 @@ export class AiAssistancePanel extends UI.Panel.Panel {
884
948
  // So we can just reuse it
885
949
  return;
886
950
  }
887
- const conversation = targetConversationType ?
888
- new AiAssistanceModel.AiConversation.AiConversation(
889
- targetConversationType, [], undefined, false, this.#aidaClient, this.#changeManager, false,
890
- this.#handlePerformanceRecordAndReload.bind(this), this.#handleInspectElement.bind(this),
891
- NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator()) :
892
- undefined;
951
+ const conversation = targetConversationType ? new AiAssistanceModel.AiConversation.AiConversation({
952
+ type: targetConversationType,
953
+ data: [],
954
+ isReadOnly: false,
955
+ aidaClient: this.#aidaClient,
956
+ changeManager: this.#changeManager,
957
+ isExternal: false,
958
+ performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
959
+ onInspectElement: this.#handleInspectElement.bind(this),
960
+ networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
961
+ lighthouseRecording: this.#handleLighthouseRun.bind(this),
962
+ }) :
963
+ undefined;
893
964
 
894
965
  this.#updateConversationState(conversation);
895
966
  }
@@ -907,18 +978,17 @@ export class AiAssistancePanel extends UI.Panel.Panel {
907
978
  if (!conversation) {
908
979
  const conversationType = this.#getDefaultConversationType();
909
980
  if (conversationType) {
910
- conversation = new AiAssistanceModel.AiConversation.AiConversation(
911
- conversationType,
912
- [],
913
- undefined,
914
- false,
915
- this.#aidaClient,
916
- this.#changeManager,
917
- false,
918
- this.#handlePerformanceRecordAndReload.bind(this),
919
- this.#handleInspectElement.bind(this),
920
- NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
921
- );
981
+ conversation = new AiAssistanceModel.AiConversation.AiConversation({
982
+ type: conversationType,
983
+ data: [],
984
+ isReadOnly: false,
985
+ aidaClient: this.#aidaClient,
986
+ changeManager: this.#changeManager,
987
+ isExternal: false,
988
+ performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
989
+ onInspectElement: this.#handleInspectElement.bind(this),
990
+ networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
991
+ });
922
992
  }
923
993
  }
924
994
 
@@ -927,7 +997,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
927
997
 
928
998
  if (this.#conversation) {
929
999
  if (this.#conversation.isEmpty && isAiAssistanceContextSelectionAgentEnabled()) {
930
- this.#conversation.setContext(this.#getConversationContext(this.#getDefaultConversationType()));
1000
+ const context = this.#getConversationContext(this.#getDefaultConversationType());
1001
+ this.#conversation.setContext(context);
931
1002
  } else {
932
1003
  const context = this.#getConversationContext(this.#conversation.type);
933
1004
  // Don't reset to the context selection agent if
@@ -945,18 +1016,17 @@ export class AiAssistancePanel extends UI.Panel.Panel {
945
1016
  async handleBreakpointConversation(uiLocation: Workspace.UISourceCode.UILocation, errorMsg?: string): Promise<void> {
946
1017
  const context = new AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext(uiLocation);
947
1018
  this.#selectedBreakpoint = context;
948
- const conversation = new AiAssistanceModel.AiConversation.AiConversation(
949
- AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT,
950
- [],
951
- undefined,
952
- false,
953
- this.#aidaClient,
954
- this.#changeManager,
955
- false,
956
- this.#handlePerformanceRecordAndReload.bind(this),
957
- this.#handleInspectElement.bind(this),
958
- NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
959
- );
1019
+ const conversation = new AiAssistanceModel.AiConversation.AiConversation({
1020
+ type: AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT,
1021
+ data: [],
1022
+ isReadOnly: false,
1023
+ aidaClient: this.#aidaClient,
1024
+ changeManager: this.#changeManager,
1025
+ isExternal: false,
1026
+ performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
1027
+ onInspectElement: this.#handleInspectElement.bind(this),
1028
+ networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
1029
+ });
960
1030
  this.#updateConversationState(conversation);
961
1031
  this.#conversation?.setContext(context);
962
1032
  this.requestUpdate();
@@ -980,6 +1050,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
980
1050
  this.#selectedFile = createFileContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UISourceCode));
981
1051
  this.#selectedBreakpoint =
982
1052
  createBreakpointContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UILocation));
1053
+ this.#selectedAccessibility = createAccessibilityContext(
1054
+ UI.Context.Context.instance().flavor(LighthousePanel.LighthousePanel.ActiveLighthouseReport));
983
1055
  this.#updateConversationState(this.#conversation);
984
1056
 
985
1057
  this.#aiAssistanceEnabledSetting?.addChangeListener(this.requestUpdate, this);
@@ -996,6 +1068,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
996
1068
  Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
997
1069
  UI.Context.Context.instance().addFlavorChangeListener(
998
1070
  Workspace.UISourceCode.UILocation, this.#handleBreakpointFlavorChange);
1071
+ UI.Context.Context.instance().addFlavorChangeListener(
1072
+ LighthousePanel.LighthousePanel.ActiveLighthouseReport, this.#handleLighthouseReportFlavorChange);
999
1073
 
1000
1074
  UI.ViewManager.ViewManager.instance().addEventListener(
1001
1075
  UI.ViewManager.Events.VIEW_VISIBILITY_CHANGED, this.#selectDefaultAgentIfNeeded, this);
@@ -1030,6 +1104,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1030
1104
  AiAssistanceModel.AIContext.AgentFocus, this.#handlePerformanceTraceFlavorChange);
1031
1105
  UI.Context.Context.instance().removeFlavorChangeListener(
1032
1106
  Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
1107
+ UI.Context.Context.instance().removeFlavorChangeListener(
1108
+ LighthousePanel.LighthousePanel.ActiveLighthouseReport, this.#handleLighthouseReportFlavorChange);
1109
+
1033
1110
  UI.ViewManager.ViewManager.instance().removeEventListener(
1034
1111
  UI.ViewManager.Events.VIEW_VISIBILITY_CHANGED, this.#selectDefaultAgentIfNeeded, this);
1035
1112
  UI.Context.Context.instance().removeFlavorChangeListener(
@@ -1129,6 +1206,17 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1129
1206
  this.#updateConversationState(this.#conversation);
1130
1207
  };
1131
1208
 
1209
+ #handleLighthouseReportFlavorChange =
1210
+ (ev: Common.EventTarget.EventTargetEvent<LighthousePanel.LighthousePanel.ActiveLighthouseReport>): void => {
1211
+ const newReport = ev.data;
1212
+
1213
+ if (this.#selectedAccessibility?.getItem() === newReport?.report) {
1214
+ return;
1215
+ }
1216
+ this.#selectedAccessibility = createAccessibilityContext(newReport);
1217
+ this.#updateConversationState(this.#conversation);
1218
+ };
1219
+
1132
1220
  #getChangeSummary(): string|undefined {
1133
1221
  if (!isAiAssistancePatchingEnabled() || !this.#conversation || this.#conversation?.isReadOnly) {
1134
1222
  return;
@@ -1227,7 +1315,12 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1227
1315
  }
1228
1316
  case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1229
1317
  return lockedString(UIStringsNotTranslate.inputPlaceholderForNoContext);
1318
+ case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
1319
+ return this.#conversation.selectedContext ?
1320
+ lockedString(UIStringsNotTranslate.inputPlaceholderForAccessibility) :
1321
+ lockedString(UIStringsNotTranslate.inputPlaceholderForAccessibilityNoContext);
1230
1322
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1323
+
1231
1324
  if (AiAssistanceModel.AiUtils.isGeminiBranding()) {
1232
1325
  return lockedString(UIStringsNotTranslate.inputPlaceholderForNoContextBranded);
1233
1326
  }
@@ -1267,7 +1360,14 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1267
1360
  }
1268
1361
  return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformance);
1269
1362
 
1363
+ case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
1364
+ if (noLogging) {
1365
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibilityEnterpriseNoLogging);
1366
+ }
1367
+ return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibility);
1368
+
1270
1369
  case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1370
+
1271
1371
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1272
1372
  if (noLogging) {
1273
1373
  return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContextEnterpriseNoLogging);
@@ -1391,18 +1491,17 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1391
1491
 
1392
1492
  let conversation = this.#conversation;
1393
1493
  if (!this.#conversation || this.#conversation.type !== targetConversationType || this.#conversation.isEmpty) {
1394
- conversation = new AiAssistanceModel.AiConversation.AiConversation(
1395
- targetConversationType,
1396
- [],
1397
- undefined,
1398
- false,
1399
- this.#aidaClient,
1400
- this.#changeManager,
1401
- false,
1402
- this.#handlePerformanceRecordAndReload.bind(this),
1403
- this.#handleInspectElement.bind(this),
1404
- NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
1405
- );
1494
+ conversation = new AiAssistanceModel.AiConversation.AiConversation({
1495
+ type: targetConversationType,
1496
+ data: [],
1497
+ isReadOnly: false,
1498
+ aidaClient: this.#aidaClient,
1499
+ changeManager: this.#changeManager,
1500
+ isExternal: false,
1501
+ performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
1502
+ onInspectElement: this.#handleInspectElement.bind(this),
1503
+ networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
1504
+ });
1406
1505
  }
1407
1506
  this.#updateConversationState(conversation);
1408
1507
  const predefinedPrompt = opts?.['prompt'];
@@ -1479,22 +1578,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1479
1578
  if (!this.#conversation) {
1480
1579
  return;
1481
1580
  }
1482
-
1483
- const markdownContent = this.#conversation.getConversationMarkdown();
1484
- const contentData = new TextUtils.ContentData.ContentData(markdownContent, false, 'text/markdown');
1485
-
1486
- const titleFormatted = Platform.StringUtilities.toSnakeCase(this.#conversation.title || '');
1487
- const prefix = 'devtools_';
1488
- const suffix = '.md';
1489
- const maxTitleLength = 64 - prefix.length - suffix.length;
1490
- let finalTitle = titleFormatted || 'conversation';
1491
- if (finalTitle.length > maxTitleLength) {
1492
- finalTitle = finalTitle.substring(0, maxTitleLength);
1493
- }
1494
- const filename = `${prefix}${finalTitle}${suffix}` as Platform.DevToolsPath.RawPathString;
1495
-
1496
- await Workspace.FileManager.FileManager.instance().save(filename, contentData, true);
1497
- Workspace.FileManager.FileManager.instance().close(filename);
1581
+ return await saveToDisk(this.#conversation);
1498
1582
  }
1499
1583
 
1500
1584
  async #openHistoricConversation(conversation: AiAssistanceModel.AiConversation.AiConversation): Promise<void> {
@@ -1533,7 +1617,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1533
1617
  return this.#selectedPerformanceTrace;
1534
1618
  case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1535
1619
  return this.#selectedBreakpoint;
1620
+ case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
1621
+ return this.#selectedAccessibility;
1536
1622
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1623
+
1537
1624
  case undefined:
1538
1625
  return null;
1539
1626
  }
@@ -1550,6 +1637,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1550
1637
  this.#selectedPerformanceTrace = data;
1551
1638
  } else if (data instanceof AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext) {
1552
1639
  this.#selectedBreakpoint = data;
1640
+ } else if (data instanceof AiAssistanceModel.AccessibilityAgent.AccessibilityContext) {
1641
+ this.#selectedAccessibility = data;
1553
1642
  }
1554
1643
 
1555
1644
  void VisualLogging.logFunctionCall(`context-change-${this.#conversation?.type}`);
@@ -1717,7 +1806,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1717
1806
  break;
1718
1807
  }
1719
1808
  case AiAssistanceModel.AiAgent.ResponseType.CONTEXT: {
1720
- step.title = data.title;
1809
+ step.title = lockedString(UIStringsNotTranslate.analyzingData);
1721
1810
  step.contextDetails = data.details;
1722
1811
  step.widgets = data.widgets;
1723
1812
  step.isLoading = false;
@@ -1836,9 +1925,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1836
1925
  case AiAssistanceModel.AiAgent.ResponseType.CONTEXT_CHANGE: {
1837
1926
  this.#handleConversationContextChange(data.context);
1838
1927
  step.isLoading = false;
1928
+ step.widgets = data.widgets;
1839
1929
  commitStep();
1840
1930
  step = {isLoading: true};
1841
-
1842
1931
  break;
1843
1932
  }
1844
1933
  }
@@ -1857,12 +1946,12 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1857
1946
  }
1858
1947
 
1859
1948
  // Announce as status update to screen readers when:
1860
- // * Context is received (e.g. Analyzing the prompt)
1949
+ // * Context is received (e.g. Analyzing data)
1861
1950
  // * Answer started streaming
1862
1951
  // * Answer finished streaming
1863
1952
  switch (data.type) {
1864
1953
  case AiAssistanceModel.AiAgent.ResponseType.CONTEXT:
1865
- UI.ARIAUtils.LiveAnnouncer.status(data.title);
1954
+ UI.ARIAUtils.LiveAnnouncer.status(lockedString(UIStringsNotTranslate.analyzingData));
1866
1955
  break;
1867
1956
  case AiAssistanceModel.AiAgent.ResponseType.ANSWER: {
1868
1957
  if (!data.complete && !announcedAnswerLoading) {
@@ -0,0 +1,25 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ import * as Platform from '../../core/platform/platform.js';
5
+ import type * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
6
+ import * as TextUtils from '../../models/text_utils/text_utils.js';
7
+ import * as Workspace from '../../models/workspace/workspace.js';
8
+
9
+ export async function saveToDisk(conversation: AiAssistanceModel.AiConversation.AiConversation): Promise<void> {
10
+ const markdownContent = conversation.getConversationMarkdown();
11
+ const contentData = new TextUtils.ContentData.ContentData(markdownContent, false, 'text/markdown');
12
+
13
+ const titleFormatted = Platform.StringUtilities.toSnakeCase(conversation.title || '');
14
+ const prefix = 'devtools_';
15
+ const suffix = '.md';
16
+ const maxTitleLength = 64 - prefix.length - suffix.length;
17
+ let finalTitle = titleFormatted || 'conversation';
18
+ if (finalTitle.length > maxTitleLength) {
19
+ finalTitle = finalTitle.substring(0, maxTitleLength);
20
+ }
21
+ const filename = `${prefix}${finalTitle}${suffix}` as Platform.DevToolsPath.RawPathString;
22
+
23
+ await Workspace.FileManager.FileManager.instance().save(filename, contentData, true);
24
+ Workspace.FileManager.FileManager.instance().close(filename);
25
+ }
@@ -9,6 +9,8 @@ export * from './components/MarkdownRendererWithCodeBlock.js';
9
9
  export * from './SelectWorkspaceDialog.js';
10
10
  export * as ChatMessage from './components/ChatMessage.js';
11
11
  export * as ExploreWidget from './components/ExploreWidget.js';
12
+ export * as ExportForAgentsDialog from './components/ExportForAgentsDialog.js';
12
13
  export * as PatchWidget from './PatchWidget.js';
13
14
  export * as DisabledWidget from './components/DisabledWidget.js';
14
15
  export * as WalkthroughView from './components/WalkthroughView.js';
16
+ export * as ExportConversation from './ExportConversation.js';
@@ -347,6 +347,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
347
347
  PanelUtils.PanelUtils.getIconForNetworkRequest(input.context.getItem()) :
348
348
  input.context instanceof AiAssistanceModel.FileAgent.FileContext ?
349
349
  PanelUtils.PanelUtils.getIconForSourceFile(input.context.getItem()) :
350
+ input.context instanceof AiAssistanceModel.AccessibilityAgent.AccessibilityContext ?
351
+ html`<devtools-icon class="icon" name="performance" title="Lighthouse"></devtools-icon>` :
350
352
  input.context instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext ?
351
353
  html`<devtools-icon class="icon" name="performance" title="Performance"></devtools-icon>` :
352
354
  Lit.nothing}