chrome-devtools-frontend 1.0.1674545 → 1.0.1676824

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 (258) hide show
  1. package/.agents/skills/devtools-ux-writing-refactor/SKILL.md +26 -9
  2. package/WATCHLISTS +0 -4
  3. package/front_end/core/common/ParsedURL.ts +5 -1
  4. package/front_end/core/common/SettingRegistration.ts +29 -8
  5. package/front_end/core/common/Settings.ts +0 -77
  6. package/front_end/core/root/Runtime.ts +4 -5
  7. package/front_end/core/sdk/CSSMetadata.ts +5 -9
  8. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +8 -28
  9. package/front_end/core/sdk/DebuggerModel.ts +50 -30
  10. package/front_end/core/sdk/ResourceTreeModel.ts +20 -1
  11. package/front_end/core/sdk/Script.ts +9 -53
  12. package/front_end/core/sdk/TargetManager.ts +18 -0
  13. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +213 -23
  14. package/front_end/entrypoints/main/MainImpl.ts +32 -0
  15. package/front_end/foundation/Universe.ts +44 -29
  16. package/front_end/generated/InspectorBackendCommands.ts +3 -1
  17. package/front_end/generated/SupportedCSSProperties.ts +21 -4
  18. package/front_end/generated/protocol-mapping.d.ts +14 -0
  19. package/front_end/generated/protocol-proxy-api.d.ts +10 -0
  20. package/front_end/generated/protocol.ts +35 -0
  21. package/front_end/models/ai_assistance/AiAgent2.ts +11 -0
  22. package/front_end/models/ai_assistance/AiConversation.ts +22 -5
  23. package/front_end/models/ai_assistance/README.md +52 -26
  24. package/front_end/models/ai_assistance/agents/AiAgent.ts +54 -8
  25. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
  26. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -192
  27. package/front_end/models/ai_assistance/agents/StorageAgent.ts +8 -87
  28. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -1
  29. package/front_end/models/ai_assistance/ai_assistance.ts +16 -0
  30. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +124 -0
  31. package/front_end/models/ai_assistance/contexts/StorageContext.ts +111 -0
  32. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +69 -1
  33. package/front_end/models/ai_assistance/skills/README.md +63 -1
  34. package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
  35. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +4 -0
  36. package/front_end/models/ai_assistance/skills/performance.md +8 -0
  37. package/front_end/models/ai_assistance/skills/sources.md +16 -0
  38. package/front_end/models/ai_assistance/skills/storage.md +31 -0
  39. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +101 -0
  40. package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +83 -0
  41. package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +106 -0
  42. package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +104 -0
  43. package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +81 -0
  44. package/front_end/models/ai_assistance/tools/ListSources.ts +116 -0
  45. package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +90 -0
  46. package/front_end/models/ai_assistance/tools/Tool.ts +22 -1
  47. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +14 -0
  48. package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -0
  49. package/front_end/models/bindings/CompilerScriptMapping.ts +4 -0
  50. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
  51. package/front_end/models/bindings/ResourceScriptMapping.ts +3 -201
  52. package/front_end/models/bindings/SASSSourceMapping.ts +6 -0
  53. package/front_end/models/breakpoints/BreakpointManager.ts +2 -49
  54. package/front_end/models/emulation/DeviceModeModel.ts +60 -71
  55. package/front_end/models/emulation/EmulatedDevices.ts +18 -66
  56. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +27 -0
  57. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +10 -2
  58. package/front_end/models/issues_manager/descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
  59. package/front_end/models/issues_manager/descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
  60. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
  61. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  62. package/front_end/models/persistence/AutomaticFileSystemManager.ts +2 -2
  63. package/front_end/models/persistence/IsolatedFileSystem.ts +7 -8
  64. package/front_end/models/persistence/IsolatedFileSystemManager.ts +22 -31
  65. package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
  66. package/front_end/models/persistence/persistence-meta.ts +9 -9
  67. package/front_end/models/trace/types/TraceEvents.ts +36 -0
  68. package/front_end/models/workspace/FileManager.ts +13 -6
  69. package/front_end/panels/accessibility/ARIAAttributesView.ts +3 -3
  70. package/front_end/panels/accessibility/AccessibilityNodeView.ts +36 -36
  71. package/front_end/panels/accessibility/AccessibilityStrings.ts +168 -168
  72. package/front_end/panels/accessibility/SourceOrderView.ts +7 -7
  73. package/front_end/panels/accessibility/accessibility-meta.ts +2 -2
  74. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -5
  75. package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +2 -3
  76. package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
  77. package/front_end/panels/ai_assistance/components/ChatMessage.ts +27 -2
  78. package/front_end/panels/application/IndexedDBViews.ts +65 -63
  79. package/front_end/panels/application/WebMCPView.ts +29 -12
  80. package/front_end/panels/application/components/AdsView.ts +24 -1
  81. package/front_end/panels/application/components/adsView.css +27 -21
  82. package/front_end/panels/autofill/AutofillView.ts +12 -12
  83. package/front_end/panels/autofill/autofill-meta.ts +2 -2
  84. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +5 -5
  85. package/front_end/panels/common/BadgeNotification.ts +8 -8
  86. package/front_end/panels/common/ExtensionServer.ts +21 -1
  87. package/front_end/panels/common/GdpSignUpDialog.ts +16 -16
  88. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +5 -6
  89. package/front_end/panels/common/PersistenceUtils.ts +2 -2
  90. package/front_end/panels/common/common.ts +0 -97
  91. package/front_end/panels/console/ConsoleInsightTeaser.ts +2 -2
  92. package/front_end/panels/console/ConsolePinPane.ts +2 -2
  93. package/front_end/panels/console/ConsoleView.ts +20 -19
  94. package/front_end/panels/elements/ElementsTreeElement.ts +550 -327
  95. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  96. package/front_end/panels/elements/LayoutPane.ts +2 -8
  97. package/front_end/panels/event_listeners/EventListenersView.ts +8 -4
  98. package/front_end/panels/issues/AffectedTrackingSitesView.ts +25 -14
  99. package/front_end/panels/js_timeline/js_timeline-meta.ts +8 -8
  100. package/front_end/panels/layer_viewer/LayerDetailsView.ts +30 -30
  101. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +6 -6
  102. package/front_end/panels/layer_viewer/LayerViewHost.ts +1 -1
  103. package/front_end/panels/layer_viewer/Layers3DView.ts +11 -11
  104. package/front_end/panels/layer_viewer/PaintProfilerView.ts +8 -8
  105. package/front_end/panels/layer_viewer/TransformController.ts +3 -3
  106. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +11 -11
  107. package/front_end/panels/media/PlayerMessagesView.ts +149 -68
  108. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +1 -58
  109. package/front_end/panels/mobile_throttling/mobile_throttling.ts +0 -10
  110. package/front_end/panels/network/NetworkPanel.ts +1 -1
  111. package/front_end/panels/network/RequestPayloadView.ts +1 -0
  112. package/front_end/panels/profiler/HeapSnapshotView.ts +0 -2
  113. package/front_end/panels/profiler/heapProfiler.css +0 -9
  114. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +7 -0
  115. package/front_end/panels/recorder/RecorderPanel.ts +2 -3
  116. package/front_end/panels/screencast/ScreencastView.ts +148 -138
  117. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -2
  118. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -2
  119. package/front_end/panels/sources/DebuggerPlugin.ts +9 -58
  120. package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
  121. package/front_end/panels/sources/UISourceCodeFrame.ts +3 -8
  122. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +4 -2
  123. package/front_end/panels/timeline/TimelineController.ts +36 -64
  124. package/front_end/panels/timeline/TimelinePanel.ts +11 -8
  125. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -2
  126. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -2
  127. package/front_end/panels/timeline/timelinePanel.css +0 -10
  128. package/front_end/panels/utils/utils.ts +7 -7
  129. package/front_end/services/tracing/PerformanceTracing.ts +5 -17
  130. package/front_end/third_party/chromium/README.chromium +1 -1
  131. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  132. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  133. package/front_end/third_party/codemirror.next/package.json +2 -2
  134. package/front_end/third_party/codemirror.next/rebuild.sh +4 -1
  135. package/front_end/ui/comments/CommentAnchorResolver.ts +558 -0
  136. package/front_end/ui/comments/CommentManager.ts +640 -0
  137. package/front_end/ui/comments/CommentsOverlayWidget.ts +121 -0
  138. package/front_end/ui/comments/comments.ts +13 -0
  139. package/front_end/ui/comments/commentsOverlay.css +49 -0
  140. package/front_end/{panels/common → ui/components/dialogs}/FreDialog.ts +6 -6
  141. package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +96 -0
  142. package/front_end/ui/components/dialogs/dialogs.ts +4 -0
  143. package/front_end/ui/components/settings/SettingCheckbox.ts +3 -3
  144. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionDisclaimer.ts +13 -13
  145. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +7 -6
  146. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionTeaser.ts +43 -46
  147. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -26
  148. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationTeaser.ts +10 -10
  149. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationUpgradeDialog.ts +5 -5
  150. package/front_end/ui/components/text_editor/text_editor.ts +4 -0
  151. package/front_end/ui/legacy/Toolbar.ts +1 -1
  152. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +40 -0
  153. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +11 -3
  154. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +270 -162
  155. package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +5 -0
  156. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -16
  157. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +5 -12
  158. package/front_end/ui/legacy/components/source_frame/JSONView.ts +8 -1
  159. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -2
  160. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -0
  161. package/front_end/ui/settings/SettingUIRegistration.ts +59 -6
  162. package/front_end/ui/visual_logging/Debugging.ts +1 -5
  163. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  164. package/front_end/ui/visual_logging/LoggingConfig.ts +21 -0
  165. package/front_end/ui/visual_logging/visual_logging.ts +9 -0
  166. package/mcp/mcp.ts +6 -1
  167. package/package.json +1 -1
  168. package/front_end/Images/toolbarResizerVertical.png +0 -0
  169. package/front_end/emulated_devices/MotoG4-landscape.svg +0 -155
  170. package/front_end/emulated_devices/MotoG4-portrait.svg +0 -155
  171. package/front_end/emulated_devices/Nexus5X-landscape.svg +0 -19
  172. package/front_end/emulated_devices/Nexus5X-portrait.svg +0 -19
  173. package/front_end/emulated_devices/Nexus6P-landscape.svg +0 -50
  174. package/front_end/emulated_devices/Nexus6P-portrait.svg +0 -54
  175. package/front_end/emulated_devices/google-nest-hub-horizontal.png +0 -0
  176. package/front_end/emulated_devices/google-nest-hub-max-horizontal.png +0 -0
  177. package/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png +0 -0
  178. package/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png +0 -0
  179. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png +0 -0
  180. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png +0 -0
  181. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png +0 -0
  182. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png +0 -0
  183. package/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png +0 -0
  184. package/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png +0 -0
  185. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png +0 -0
  186. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png +0 -0
  187. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png +0 -0
  188. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png +0 -0
  189. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png +0 -0
  190. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png +0 -0
  191. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png +0 -0
  192. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png +0 -0
  193. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png +0 -0
  194. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png +0 -0
  195. package/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png +0 -0
  196. package/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png +0 -0
  197. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png +0 -0
  198. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png +0 -0
  199. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png +0 -0
  200. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png +0 -0
  201. package/front_end/emulated_devices/iPad-landscape.svg +0 -73
  202. package/front_end/emulated_devices/iPad-portrait.svg +0 -76
  203. package/front_end/emulated_devices/iPhone5-landscape.svg +0 -99
  204. package/front_end/emulated_devices/iPhone5-portrait.svg +0 -83
  205. package/front_end/emulated_devices/iPhone6-landscape.svg +0 -111
  206. package/front_end/emulated_devices/iPhone6-portrait.svg +0 -116
  207. package/front_end/emulated_devices/iPhone6Plus-landscape.svg +0 -118
  208. package/front_end/emulated_devices/iPhone6Plus-portrait.svg +0 -116
  209. package/front_end/emulated_devices/optimized/MotoG4-landscape.avif +0 -0
  210. package/front_end/emulated_devices/optimized/MotoG4-portrait.avif +0 -0
  211. package/front_end/emulated_devices/optimized/Nexus5X-landscape.avif +0 -0
  212. package/front_end/emulated_devices/optimized/Nexus5X-portrait.avif +0 -0
  213. package/front_end/emulated_devices/optimized/Nexus6P-landscape.avif +0 -0
  214. package/front_end/emulated_devices/optimized/Nexus6P-portrait.avif +0 -0
  215. package/front_end/emulated_devices/optimized/README.md +0 -9
  216. package/front_end/emulated_devices/optimized/google-nest-hub-horizontal.avif +0 -0
  217. package/front_end/emulated_devices/optimized/google-nest-hub-max-horizontal.avif +0 -0
  218. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-1x.avif +0 -0
  219. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-2x.avif +0 -0
  220. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-1x.avif +0 -0
  221. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-2x.avif +0 -0
  222. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-1x.avif +0 -0
  223. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-2x.avif +0 -0
  224. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-1x.avif +0 -0
  225. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-2x.avif +0 -0
  226. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-1x.avif +0 -0
  227. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-2x.avif +0 -0
  228. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-1x.avif +0 -0
  229. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-2x.avif +0 -0
  230. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-1x.avif +0 -0
  231. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-2x.avif +0 -0
  232. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-1x.avif +0 -0
  233. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-2x.avif +0 -0
  234. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-1x.avif +0 -0
  235. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-2x.avif +0 -0
  236. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-1x.avif +0 -0
  237. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-2x.avif +0 -0
  238. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-1x.avif +0 -0
  239. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-2x.avif +0 -0
  240. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-1x.avif +0 -0
  241. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-2x.avif +0 -0
  242. package/front_end/emulated_devices/optimized/iPad-landscape.avif +0 -0
  243. package/front_end/emulated_devices/optimized/iPad-portrait.avif +0 -0
  244. package/front_end/emulated_devices/optimized/iPhone5-landscape.avif +0 -0
  245. package/front_end/emulated_devices/optimized/iPhone5-portrait.avif +0 -0
  246. package/front_end/emulated_devices/optimized/iPhone6-landscape.avif +0 -0
  247. package/front_end/emulated_devices/optimized/iPhone6-portrait.avif +0 -0
  248. package/front_end/emulated_devices/optimized/iPhone6Plus-landscape.avif +0 -0
  249. package/front_end/emulated_devices/optimized/iPhone6Plus-portrait.avif +0 -0
  250. package/front_end/emulated_devices/optimized/optimized_images.gni +0 -53
  251. package/front_end/models/ai_assistance/agents/README.md +0 -136
  252. package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +0 -92
  253. /package/front_end/{panels/common → ui/components/dialogs}/freDialog.css +0 -0
  254. /package/front_end/{panels/common/common.css → ui/components/dialogs/typeToAllowDialog.css} +0 -0
  255. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionDisclaimer.css +0 -0
  256. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionTeaser.css +0 -0
  257. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationTeaser.css +0 -0
  258. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationUpgradeDialog.css +0 -0
@@ -14,12 +14,11 @@ import * as Tracing from '../../../services/tracing/tracing.js';
14
14
  import * as Logs from '../../logs/logs.js';
15
15
  import * as Trace from '../../trace/trace.js';
16
16
  import {canResourceContentsBeReadForTrace} from '../AiOrigins.js';
17
- import type {PerformanceTraceContext} from '../contexts/PerformanceTraceContext.js';
18
- import {sanitizeHeaders} from '../data_formatters/NetworkRequestFormatter.js';
17
+ import type {MainThreadSectionLabel, PerformanceTraceContext} from '../contexts/PerformanceTraceContext.js';
19
18
  import {
20
19
  PerformanceInsightFormatter,
21
20
  } from '../data_formatters/PerformanceInsightFormatter.js';
22
- import {PerformanceTraceFormatter} from '../data_formatters/PerformanceTraceFormatter.js';
21
+ import {formatEventForAI, PerformanceTraceFormatter} from '../data_formatters/PerformanceTraceFormatter.js';
23
22
  import {debugLog} from '../debug.js';
24
23
  import {AICallTree} from '../performance/AICallTree.js';
25
24
  import type {AgentFocus} from '../performance/AIContext.js';
@@ -49,13 +48,6 @@ const UIStringsNotTranslated = {
49
48
  } as const;
50
49
  const lockedString = i18n.i18n.lockedString;
51
50
 
52
- /**
53
- * Labels used to identify specific periods or categories in the trace for getting main thread summary.
54
- * Supports hardcoded phases, dynamic navigation IDs (`NAVIGATION_X`), and insight models.
55
- */
56
- export type MainThreadSectionLabel = 'nav-to-lcp'|'lcp-ttfb'|'lcp-render-delay'|'trace-bounds'|'NO_NAVIGATION'|
57
- `NAVIGATION_${string}`|keyof Trace.Insights.Types.InsightModels;
58
-
59
51
  /**
60
52
  * WARNING: preamble defined in code is only used when userTier is
61
53
  * TESTERS. Otherwise, a server-side preamble is used (see
@@ -196,39 +188,14 @@ enum ScorePriority {
196
188
  // 16k Tokens * ~4 char per token.
197
189
  const MAX_FUNCTION_RESULT_BYTE_LENGTH = 16384 * 4;
198
190
 
199
- const STATIC_LABEL_NAMES: Record<string, string> = {
200
- 'nav-to-lcp': 'navigation to LCP',
201
- 'lcp-ttfb': 'LCP to TTFB',
202
- 'lcp-render-delay': 'LCP render delay',
203
- 'trace-bounds': 'the entire trace',
204
- NO_NAVIGATION: 'the period before the first navigation',
205
- };
206
-
207
- /**
208
- * Converts the label name we use in the code to a human readable one that is
209
- * shown to the user.
210
- */
211
- export function getLabelName(label: MainThreadSectionLabel, focus: AgentFocus): string {
212
- if (STATIC_LABEL_NAMES[label]) {
213
- return STATIC_LABEL_NAMES[label];
214
- }
215
-
216
- const {parsedTrace} = focus;
217
- const insightSetById = parsedTrace.insights?.get(label as Trace.Types.Events.NavigationId);
218
- if (insightSetById) {
219
- return `navigation to ${insightSetById.url.href}`;
191
+ function getInsightModel(
192
+ model: Trace.Insights.Types.InsightModels,
193
+ key: string,
194
+ ): Trace.Insights.Types.InsightModels[keyof Trace.Insights.Types.InsightModels]|undefined {
195
+ if (Object.prototype.hasOwnProperty.call(model, key)) {
196
+ return model[key as keyof Trace.Insights.Types.InsightModels];
220
197
  }
221
-
222
- // Go through all the insights we have to find the first one that matches to find the title.
223
- // TODO(b/505291090): make it easier to look up Insight titles from a key.
224
- for (const insightSet of parsedTrace.insights?.values() ?? []) {
225
- const model = insightSet.model[label as keyof Trace.Insights.Types.InsightModels];
226
- if (model) {
227
- return `${model.title} insight`;
228
- }
229
- }
230
-
231
- return label;
198
+ return undefined;
232
199
  }
233
200
 
234
201
  export interface PerformanceAgentOptions extends AgentOptions {
@@ -806,14 +773,13 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
806
773
  const insightSet = parsedTrace.insights?.get(params.insightSetId);
807
774
  if (!insightSet) {
808
775
  const valid = ([...parsedTrace.insights?.values() ?? []])
809
- .map(
810
- insightSet => `id: ${insightSet.id}, url: ${insightSet.url}, bounds: ${
811
- this.#formatter?.serializeBounds(insightSet.bounds)}`)
776
+ .map(insightSet => `id: ${insightSet.id}, url: ${insightSet.url}, bounds: ${
777
+ this.#formatter?.serializeBounds(insightSet.bounds)}`)
812
778
  .join('; ');
813
779
  return {error: `Invalid insight set id. Valid insight set ids are: ${valid}`};
814
780
  }
815
781
 
816
- const insight = insightSet.model[params.insightName as keyof Trace.Insights.Types.InsightModels];
782
+ const insight = getInsightModel(insightSet.model, params.insightName);
817
783
  if (!insight) {
818
784
  const valid = Object.keys(insightSet.model).join(', ');
819
785
  return {error: `No insight available. Valid insight names are: ${valid}`};
@@ -929,20 +895,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
929
895
  },
930
896
  });
931
897
 
932
- const createBounds =
933
- (min?: Trace.Types.Timing.Micro, max?: Trace.Types.Timing.Micro): Trace.Types.Timing.TraceWindowMicro|null => {
934
- const {min: bMin, max: bMax} = parsedTrace.data.Meta.traceBounds;
935
- const clampedMin = Math.max(min ?? bMin, bMin);
936
- const clampedMax = Math.min(max ?? bMax, bMax);
937
-
938
- if (clampedMin > clampedMax) {
939
- return null;
940
- }
941
-
942
- return Trace.Helpers.Timing.traceWindowFromMicroSeconds(
943
- clampedMin as Trace.Types.Timing.Micro, clampedMax as Trace.Types.Timing.Micro);
944
- };
945
-
946
898
  this.declareFunction<{label: MainThreadSectionLabel}, {summary: string}>('getMainThreadTrackSummaryByLabel', {
947
899
  description:
948
900
  'Returns a focused, detailed summary of the main thread for a predefined labeled period. Use this to get more relevant detail than the initial trace summary before diagnosing issues.',
@@ -961,7 +913,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
961
913
  required: ['label'],
962
914
  },
963
915
  displayInfoFromArgs: args => {
964
- const labelName = getLabelName(args.label, focus);
916
+ const labelName = context.getLabelName(args.label);
965
917
  return {
966
918
  title: lockedString(`${UIStringsNotTranslated.mainThreadActivity}: ${labelName}`),
967
919
  action: `getMainThreadTrackSummaryByLabel('${args.label}')`,
@@ -970,7 +922,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
970
922
  handler: async args => {
971
923
  debugLog('Function call: getMainThreadTrackSummaryByLabel');
972
924
 
973
- const bounds = this.#getBoundsForLabel(args.label, focus);
925
+ const bounds = context.getBoundsForLabel(args.label);
974
926
  if (!bounds) {
975
927
  return {error: `Invalid label: ${args.label}`};
976
928
  }
@@ -1018,7 +970,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
1018
970
  throw new Error('missing formatter');
1019
971
  }
1020
972
 
1021
- const bounds = createBounds(args.min, args.max);
973
+ const bounds = context.createBounds(args.min, args.max);
1022
974
  if (!bounds) {
1023
975
  return {error: 'invalid bounds'};
1024
976
  }
@@ -1316,67 +1268,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
1316
1268
  });
1317
1269
  }
1318
1270
 
1319
- #getBoundsForLabel(label: MainThreadSectionLabel, focus: AgentFocus): Trace.Types.Timing.TraceWindowMicro|null {
1320
- const {parsedTrace} = focus;
1321
- const insightSet = focus.primaryInsightSet;
1322
-
1323
- if (label === 'nav-to-lcp') {
1324
- if (insightSet) {
1325
- const lcp = Trace.Insights.Common.getLCP(insightSet);
1326
- if (lcp) {
1327
- return Trace.Helpers.Timing.traceWindowFromMicroSeconds(
1328
- insightSet.bounds.min, lcp.event.ts as Trace.Types.Timing.Micro);
1329
- }
1330
- }
1331
- return null;
1332
- }
1333
-
1334
- if (label === 'lcp-ttfb') {
1335
- if (insightSet) {
1336
- const subparts = insightSet.model.LCPBreakdown?.subparts;
1337
- if (subparts?.ttfb) {
1338
- return subparts.ttfb;
1339
- }
1340
- }
1341
- return null;
1342
- }
1343
-
1344
- if (label === 'lcp-render-delay') {
1345
- if (insightSet) {
1346
- const subparts = insightSet.model.LCPBreakdown?.subparts;
1347
- if (subparts?.renderDelay) {
1348
- return subparts.renderDelay;
1349
- }
1350
- }
1351
- return null;
1352
- }
1353
-
1354
- if (label === 'trace-bounds') {
1355
- return parsedTrace.data.Meta.traceBounds;
1356
- }
1357
-
1358
- const insightSetById = parsedTrace.insights?.get(label as Trace.Types.Events.NavigationId);
1359
- if (insightSetById) {
1360
- return insightSetById.bounds;
1361
- }
1362
-
1363
- if (insightSet) {
1364
- const model = insightSet.model[label as keyof Trace.Insights.Types.InsightModels];
1365
- if (model) {
1366
- return Trace.Insights.Common.insightBounds(model, insightSet.bounds);
1367
- }
1368
- }
1369
-
1370
- for (const is of parsedTrace.insights?.values() ?? []) {
1371
- const model = is.model[label as keyof Trace.Insights.Types.InsightModels];
1372
- if (model) {
1373
- return Trace.Insights.Common.insightBounds(model, is.bounds);
1374
- }
1375
- }
1376
-
1377
- return null;
1378
- }
1379
-
1380
1271
  async #getNetworkRequestImageData(lcpRequest: Trace.Types.Events.SyntheticNetworkRequest):
1381
1272
  Promise<TextUtils.ContentData.ContentData|undefined> {
1382
1273
  const target = this.targetManager.primaryPageTarget();
@@ -1398,71 +1289,3 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
1398
1289
  return undefined;
1399
1290
  }
1400
1291
  }
1401
-
1402
- /**
1403
- * Serializes a trace event to a JSON string for AI consumption,
1404
- * ensuring sensitive data (like headers and raw script source code)
1405
- * is sanitized or redacted.
1406
- */
1407
- function formatEventForAI(event: Trace.Types.Events.Event): string {
1408
- if (Trace.Types.Events.isSyntheticNetworkRequest(event)) {
1409
- return JSON.stringify({
1410
- ...event,
1411
- args: {
1412
- ...event.args,
1413
- data: {
1414
- ...event.args.data,
1415
- responseHeaders: event.args.data.responseHeaders ? sanitizeHeaders(event.args.data.responseHeaders) : null,
1416
- },
1417
- },
1418
- });
1419
- }
1420
-
1421
- if (Trace.Types.Events.isResourceReceiveResponse(event)) {
1422
- return JSON.stringify({
1423
- ...event,
1424
- args: {
1425
- ...event.args,
1426
- data: {
1427
- ...event.args.data,
1428
- headers: event.args.data.headers ? sanitizeHeaders(event.args.data.headers) : undefined,
1429
- },
1430
- },
1431
- });
1432
- }
1433
-
1434
- if (Trace.Types.Events.isRundownScriptSource(event)) {
1435
- // Redact sensitive cross-origin script source text.
1436
- const safeData: Omit<Trace.Types.Events.RundownScriptSource['args']['data'], 'sourceText'> = {
1437
- isolate: event.args.data.isolate,
1438
- scriptId: event.args.data.scriptId,
1439
- length: event.args.data.length,
1440
- };
1441
- return JSON.stringify({
1442
- ...event,
1443
- args: {
1444
- ...event.args,
1445
- data: safeData,
1446
- },
1447
- });
1448
- }
1449
-
1450
- if (Trace.Types.Events.isRundownScriptSourceLarge(event)) {
1451
- // Redact sensitive cross-origin script source text.
1452
- const safeData: Omit<Trace.Types.Events.RundownScriptSourceLarge['args']['data'], 'sourceText'> = {
1453
- isolate: event.args.data.isolate,
1454
- scriptId: event.args.data.scriptId,
1455
- splitIndex: event.args.data.splitIndex,
1456
- splitCount: event.args.data.splitCount,
1457
- };
1458
- return JSON.stringify({
1459
- ...event,
1460
- args: {
1461
- ...event.args,
1462
- data: safeData,
1463
- },
1464
- });
1465
- }
1466
-
1467
- return JSON.stringify(event);
1468
- }
@@ -14,8 +14,7 @@ import {
14
14
  type AgentOptions,
15
15
  AiAgent,
16
16
  type ContextResponse,
17
- ConversationContext,
18
- type ConversationSuggestions,
17
+ type ConversationContext,
19
18
  type RequestOptions,
20
19
  ResponseType,
21
20
  } from './AiAgent.js';
@@ -68,7 +67,7 @@ function isSamePrimaryPageOrigin(targetManager: SDK.TargetManager.TargetManager,
68
67
  return isSamePageOrigin(primaryPageTarget, context);
69
68
  }
70
69
 
71
- export function isSamePageOrigin(target: SDK.Target.Target|null, context?: ConversationContext<StorageItem>): boolean {
70
+ export function isSamePageOrigin(target: SDK.Target.Target|null, context?: ConversationContext<unknown>): boolean {
72
71
  if (!target || !context) {
73
72
  return false;
74
73
  }
@@ -85,84 +84,6 @@ function resolveTargetOrigins(context?: ConversationContext<StorageItem>, origin
85
84
  return uniqueOrigins.slice(0, MAX_TARGET_ORIGINS);
86
85
  }
87
86
 
88
- export class StorageContext extends ConversationContext<StorageItem> {
89
- #item: StorageItem;
90
-
91
- constructor(item: StorageItem) {
92
- super();
93
- this.#item = item;
94
- }
95
-
96
- override getURL(): string {
97
- return this.#item.primaryTargetOrigin;
98
- }
99
-
100
- override getItem(): StorageItem {
101
- return this.#item;
102
- }
103
-
104
- override getTitle(): string {
105
- if (this.#item instanceof CookieItem) {
106
- if (this.#item.name) {
107
- return `cookie: ${this.#item.name}${this.#item.origin ? ` ${this.#item.origin}` : ''}`;
108
- }
109
- return `cookies${this.#item.isGenericContext ? '' : `: ${this.#item.origin}`}`;
110
- }
111
- if (this.#item instanceof DOMStorageItem) {
112
- if (this.#item.key) {
113
- return `entry: ${this.#item.key}${this.#item.origin ? ` ${this.#item.origin}` : ''}`;
114
- }
115
- const prefix = this.#item.type === 'localStorage' ? 'local storage' : 'session storage';
116
- return `${prefix}${this.#item.isGenericContext ? '' : `: ${this.#item.origin}`}`;
117
- }
118
- return `Storage: ${this.getOrigin()}`;
119
- }
120
-
121
- override async getSuggestions(): Promise<ConversationSuggestions|undefined> {
122
- if (this.#item instanceof CookieItem) {
123
- if (this.#item.name) {
124
- return [
125
- {
126
- title: 'Why is this cookie set?',
127
- jslogContext: 'storage-cookie',
128
- },
129
- {
130
- title: 'Explain the value of this cookie',
131
- jslogContext: 'storage-cookie',
132
- },
133
- ];
134
- }
135
- return [
136
- {
137
- title: 'Explain the cookies set by this page',
138
- jslogContext: 'storage-cookie',
139
- },
140
- ];
141
- }
142
- if (this.#item instanceof DOMStorageItem) {
143
- if (this.#item.key) {
144
- return [
145
- {
146
- title: 'What is the purpose of this storage entry?',
147
- jslogContext: 'storage-domstorage',
148
- },
149
- {
150
- title: 'Explain the value of this storage entry',
151
- jslogContext: 'storage-domstorage',
152
- },
153
- ];
154
- }
155
- return [
156
- {
157
- title: 'Explain these storage items',
158
- jslogContext: 'storage-domstorage',
159
- },
160
- ];
161
- }
162
- return undefined;
163
- }
164
- }
165
-
166
87
  // Maximum character length of values allowed.
167
88
  const MAX_NUM_CHAR_LENGTH = 10000;
168
89
 
@@ -281,7 +202,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
281
202
  },
282
203
 
283
204
  handler: async args => {
284
- this.disableServerSideLogging();
205
+ this.setServerSideLoggingActive(false);
285
206
  if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
286
207
  return {error: 'No origin available or not allowed.'};
287
208
  }
@@ -367,7 +288,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
367
288
  },
368
289
 
369
290
  handler: async (args, options) => {
370
- this.disableServerSideLogging();
291
+ this.setServerSideLoggingActive(false);
371
292
  if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
372
293
  return {error: 'No origin available or not allowed.'};
373
294
  }
@@ -467,7 +388,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
467
388
  };
468
389
  },
469
390
  handler: async args => {
470
- this.disableServerSideLogging();
391
+ this.setServerSideLoggingActive(false);
471
392
  if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
472
393
  return {error: 'No origin available or not allowed.'};
473
394
  }
@@ -527,7 +448,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
527
448
  };
528
449
  },
529
450
  handler: async (args, options) => {
530
- this.disableServerSideLogging();
451
+ this.setServerSideLoggingActive(false);
531
452
  if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
532
453
  return {error: 'No origin available or not allowed.'};
533
454
  }
@@ -684,9 +605,9 @@ export class StorageAgent extends AiAgent<StorageItem> {
684
605
  protected override async preRun(): Promise<void> {
685
606
  const item = this.context?.getItem();
686
607
  if (item instanceof CookieItem && Boolean(item.name)) {
687
- this.disableServerSideLogging();
608
+ this.setServerSideLoggingActive(false);
688
609
  } else if (item instanceof DOMStorageItem && Boolean(item.key)) {
689
- this.disableServerSideLogging();
610
+ this.setServerSideLoggingActive(false);
690
611
  }
691
612
  }
692
613
 
@@ -365,7 +365,8 @@ Content:
365
365
  "type": "action",
366
366
  "code": "console.log('hello');",
367
367
  "output": "hello",
368
- "canceled": false
368
+ "canceled": false,
369
+ "toolName": "executeJavaScript"
369
370
  },
370
371
  {
371
372
  "type": "querying"
@@ -22,6 +22,7 @@ import * as DOMNodeContext from './contexts/DOMNodeContext.js';
22
22
  import * as FileContext from './contexts/FileContext.js';
23
23
  import * as PerformanceTraceContext from './contexts/PerformanceTraceContext.js';
24
24
  import * as RequestContext from './contexts/RequestContext.js';
25
+ import * as StorageContext from './contexts/StorageContext.js';
25
26
  import * as ConversationSummary from './ConversationSummary.js';
26
27
  import * as FileFormatter from './data_formatters/FileFormatter.js';
27
28
  import * as LighthouseFormatter from './data_formatters/LighthouseFormatter.js';
@@ -42,10 +43,17 @@ import * as ExecuteJavaScript from './tools/ExecuteJavaScript.js';
42
43
  import * as GetElementAccessibilityDetails from './tools/GetElementAccessibilityDetails.js';
43
44
  import * as GetLighthouseAudits from './tools/GetLighthouseAudits.js';
44
45
  import * as GetNetworkRequestDetails from './tools/GetNetworkRequestDetails.js';
46
+ import * as GetSourceContent from './tools/GetSourceContent.js';
45
47
  import * as GetStyles from './tools/GetStyles.js';
48
+ import * as GetTraceEventByKey from './tools/GetTraceEventByKey.js';
49
+ import * as GetTraceMainThreadSummary from './tools/GetTraceMainThreadSummary.js';
50
+ import * as GetTraceNetworkSummary from './tools/GetTraceNetworkSummary.js';
46
51
  import * as ListNetworkRequests from './tools/ListNetworkRequests.js';
52
+ import * as ListPageOrigins from './tools/ListPageOrigins.js';
53
+ import * as ListSources from './tools/ListSources.js';
47
54
  import * as RecordPerformanceTrace from './tools/RecordPerformanceTrace.js';
48
55
  import * as ResolveDevtoolsNodePath from './tools/ResolveDevtoolsNodePath.js';
56
+ import * as SelectTraceEventByKey from './tools/SelectTraceEventByKey.js';
49
57
  import * as Tool from './tools/Tool.js';
50
58
  import * as ToolRegistry from './tools/ToolRegistry.js';
51
59
 
@@ -77,10 +85,16 @@ export {
77
85
  GetElementAccessibilityDetails,
78
86
  GetLighthouseAudits,
79
87
  GetNetworkRequestDetails,
88
+ GetSourceContent,
80
89
  GetStyles,
90
+ GetTraceEventByKey,
91
+ GetTraceMainThreadSummary,
92
+ GetTraceNetworkSummary,
81
93
  Injected,
82
94
  LighthouseFormatter,
83
95
  ListNetworkRequests,
96
+ ListPageOrigins,
97
+ ListSources,
84
98
  NetworkAgent,
85
99
  NetworkRequestFormatter,
86
100
  PerformanceAgent,
@@ -91,7 +105,9 @@ export {
91
105
  RecordPerformanceTrace,
92
106
  RequestContext,
93
107
  ResolveDevtoolsNodePath,
108
+ SelectTraceEventByKey,
94
109
  StorageAgent,
110
+ StorageContext,
95
111
  StorageItem,
96
112
  StylingAgent,
97
113
  Tool,
@@ -23,6 +23,13 @@ import {PerformanceTraceFormatter} from '../data_formatters/PerformanceTraceForm
23
23
  import type {AICallTree} from '../performance/AICallTree.js';
24
24
  import {AgentFocus} from '../performance/AIContext.js';
25
25
 
26
+ /**
27
+ * Labels used to identify specific periods or categories in the trace for getting main thread summary.
28
+ * Supports hardcoded phases, dynamic navigation IDs (`NAVIGATION_X`), and insight models.
29
+ */
30
+ export type MainThreadSectionLabel = 'nav-to-lcp'|'lcp-ttfb'|'lcp-render-delay'|'trace-bounds'|'NO_NAVIGATION'|
31
+ `NAVIGATION_${string}`|keyof Trace.Insights.Types.InsightModels;
32
+
26
33
  /**
27
34
  * The conversation context for AI queries regarding performance traces.
28
35
  * Encapsulates the user's active trace selection/focus and handles formatting
@@ -339,4 +346,121 @@ export class PerformanceTraceContext extends ConversationContext<AgentFocus> {
339
346
 
340
347
  return details.length > 0 ? (details as [ContextDetail, ...ContextDetail[]]) : null;
341
348
  }
349
+
350
+ getBoundsForLabel(label: MainThreadSectionLabel): Trace.Types.Timing.TraceWindowMicro|null {
351
+ const focus = this.#focus;
352
+ const {parsedTrace} = focus;
353
+ const insightSet = focus.primaryInsightSet;
354
+
355
+ if (label === 'nav-to-lcp') {
356
+ if (insightSet) {
357
+ const lcp = Trace.Insights.Common.getLCP(insightSet);
358
+ if (lcp) {
359
+ return Trace.Helpers.Timing.traceWindowFromMicroSeconds(insightSet.bounds.min,
360
+ lcp.event.ts as Trace.Types.Timing.Micro);
361
+ }
362
+ }
363
+ return null;
364
+ }
365
+
366
+ if (label === 'lcp-ttfb') {
367
+ if (insightSet) {
368
+ const subparts = insightSet.model.LCPBreakdown?.subparts;
369
+ if (subparts?.ttfb) {
370
+ return subparts.ttfb;
371
+ }
372
+ }
373
+ return null;
374
+ }
375
+
376
+ if (label === 'lcp-render-delay') {
377
+ if (insightSet) {
378
+ const subparts = insightSet.model.LCPBreakdown?.subparts;
379
+ if (subparts?.renderDelay) {
380
+ return subparts.renderDelay;
381
+ }
382
+ }
383
+ return null;
384
+ }
385
+
386
+ if (label === 'trace-bounds') {
387
+ return parsedTrace.data.Meta.traceBounds;
388
+ }
389
+
390
+ const insightSetById = parsedTrace.insights?.get(label as Trace.Types.Events.NavigationId);
391
+ if (insightSetById) {
392
+ return insightSetById.bounds;
393
+ }
394
+
395
+ if (insightSet) {
396
+ const model = getInsightModel(insightSet.model, label);
397
+ if (model) {
398
+ return Trace.Insights.Common.insightBounds(model, insightSet.bounds);
399
+ }
400
+ }
401
+
402
+ for (const is of parsedTrace.insights?.values() ?? []) {
403
+ const model = getInsightModel(is.model, label);
404
+ if (model) {
405
+ return Trace.Insights.Common.insightBounds(model, is.bounds);
406
+ }
407
+ }
408
+
409
+ return null;
410
+ }
411
+
412
+ getLabelName(label: MainThreadSectionLabel): string {
413
+ return getLabelName(label, this.#focus.parsedTrace);
414
+ }
415
+
416
+ createBounds(min?: number, max?: number): Trace.Types.Timing.TraceWindowMicro|null {
417
+ const {min: bMin, max: bMax} = this.#focus.parsedTrace.data.Meta.traceBounds;
418
+ const clampedMin = Math.round(Math.max(min ?? bMin, bMin));
419
+ const clampedMax = Math.round(Math.min(max ?? bMax, bMax));
420
+
421
+ if (clampedMin > clampedMax) {
422
+ return null;
423
+ }
424
+
425
+ return Trace.Helpers.Timing.traceWindowFromMicroSeconds(clampedMin as Trace.Types.Timing.Micro,
426
+ clampedMax as Trace.Types.Timing.Micro);
427
+ }
428
+ }
429
+
430
+ const STATIC_LABEL_NAMES: Record<string, string> = {
431
+ 'nav-to-lcp': 'navigation to LCP',
432
+ 'lcp-ttfb': 'LCP to TTFB',
433
+ 'lcp-render-delay': 'LCP render delay',
434
+ 'trace-bounds': 'the entire trace',
435
+ NO_NAVIGATION: 'the period before the first navigation',
436
+ };
437
+
438
+ function getInsightModel(
439
+ model: Trace.Insights.Types.InsightModels,
440
+ key: string,
441
+ ): Trace.Insights.Types.InsightModels[keyof Trace.Insights.Types.InsightModels]|undefined {
442
+ if (Object.prototype.hasOwnProperty.call(model, key)) {
443
+ return model[key as keyof Trace.Insights.Types.InsightModels];
444
+ }
445
+ return undefined;
446
+ }
447
+
448
+ function getLabelName(label: MainThreadSectionLabel, parsedTrace: Trace.TraceModel.ParsedTrace): string {
449
+ if (Object.prototype.hasOwnProperty.call(STATIC_LABEL_NAMES, label)) {
450
+ return STATIC_LABEL_NAMES[label];
451
+ }
452
+
453
+ const insightSetById = parsedTrace.insights?.get(label as Trace.Types.Events.NavigationId);
454
+ if (insightSetById) {
455
+ return `navigation to ${insightSetById.url.href}`;
456
+ }
457
+
458
+ for (const insightSet of parsedTrace.insights?.values() ?? []) {
459
+ const model = getInsightModel(insightSet.model, label);
460
+ if (model) {
461
+ return `${model.title} insight`;
462
+ }
463
+ }
464
+
465
+ return label;
342
466
  }