chrome-devtools-frontend 1.0.1547147 → 1.0.1548870

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 (212) hide show
  1. package/.stylelintrc.json +5 -1
  2. package/docs/contributing/infrastructure.md +2 -2
  3. package/eslint.config.mjs +3 -2
  4. package/front_end/Images/generate-css-vars.js +1 -1
  5. package/front_end/core/common/common.ts +0 -2
  6. package/front_end/core/i18n/collect-ui-strings.js +1 -1
  7. package/front_end/core/i18n/generate-locales-js.js +1 -1
  8. package/front_end/core/platform/HostRuntime.ts +14 -7
  9. package/front_end/core/platform/api/HostRuntime.ts +28 -3
  10. package/front_end/core/platform/browser/HostRuntime.ts +66 -5
  11. package/front_end/core/platform/node/HostRuntime.ts +76 -4
  12. package/front_end/core/sdk/AnimationModel.ts +1 -1
  13. package/front_end/core/sdk/CSSModel.ts +1 -1
  14. package/front_end/core/sdk/CSSProperty.ts +1 -1
  15. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +1 -1
  16. package/front_end/core/sdk/ConsoleModel.ts +1 -1
  17. package/front_end/core/sdk/Cookie.ts +1 -1
  18. package/front_end/core/sdk/DOMModel.ts +2 -2
  19. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  20. package/front_end/core/sdk/NetworkManager.ts +6 -0
  21. package/front_end/core/sdk/PreloadingModel.ts +1 -1
  22. package/front_end/core/sdk/RemoteObject.ts +1 -1
  23. package/front_end/core/sdk/ResourceTreeModel.ts +1 -1
  24. package/front_end/core/sdk/Script.ts +4 -4
  25. package/front_end/entrypoints/formatter_worker/HTMLFormatter.ts +2 -2
  26. package/front_end/entrypoints/formatter_worker/JavaScriptFormatter.ts +15 -18
  27. package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +8 -5
  28. package/front_end/entrypoints/main/ExecutionContextSelector.ts +1 -1
  29. package/front_end/entrypoints/main/MainImpl.ts +2 -2
  30. package/front_end/generated/Deprecation.ts +19 -0
  31. package/front_end/generated/InspectorBackendCommands.ts +4 -3
  32. package/front_end/generated/SupportedCSSProperties.js +13 -13
  33. package/front_end/generated/protocol-mapping.d.ts +2 -0
  34. package/front_end/generated/protocol-proxy-api.d.ts +4 -0
  35. package/front_end/generated/protocol.ts +16 -27
  36. package/front_end/models/ai_assistance/AiConversation.ts +104 -24
  37. package/front_end/models/ai_assistance/BuiltInAi.ts +131 -134
  38. package/front_end/models/ai_assistance/ChangeManager.ts +9 -0
  39. package/front_end/models/ai_assistance/ConversationHandler.ts +23 -48
  40. package/front_end/models/ai_assistance/agents/AiAgent.ts +8 -5
  41. package/front_end/models/ai_assistance/agents/StylingAgent.ts +0 -10
  42. package/front_end/models/formatter/FormatterWorkerPool.ts +9 -7
  43. package/front_end/models/har/Importer.ts +1 -1
  44. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +1 -1
  45. package/front_end/models/persistence/AutomaticFileSystemManager.ts +1 -1
  46. package/front_end/panels/accessibility/AccessibilityNodeView.ts +1 -1
  47. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +80 -153
  48. package/front_end/panels/ai_assistance/components/ChatView.ts +54 -31
  49. package/front_end/panels/application/ExtensionStorageModel.ts +1 -1
  50. package/front_end/panels/application/FrameDetailsView.ts +62 -34
  51. package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
  52. package/front_end/panels/application/components/components.ts +0 -2
  53. package/front_end/panels/console/ConsoleInsightTeaser.ts +166 -100
  54. package/front_end/panels/console/ConsolePrompt.ts +1 -1
  55. package/front_end/panels/console/ConsoleViewMessage.ts +77 -29
  56. package/front_end/panels/console/ConsoleViewport.ts +1 -1
  57. package/front_end/panels/console/consoleInsightTeaser.css +1 -0
  58. package/front_end/panels/coverage/CoverageModel.ts +2 -2
  59. package/front_end/panels/elements/ElementsPanel.ts +1 -1
  60. package/front_end/panels/elements/ElementsTreeOutline.ts +17 -7
  61. package/front_end/panels/elements/NodeStackTraceWidget.ts +6 -5
  62. package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -2
  63. package/front_end/panels/explain/components/ConsoleInsight.ts +1 -1
  64. package/front_end/panels/network/RequestConditionsDrawer.ts +64 -20
  65. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +1 -1
  66. package/front_end/panels/profiler/HeapSnapshotProxy.ts +15 -14
  67. package/front_end/panels/recorder/components/StepEditor.ts +1 -1
  68. package/front_end/panels/security/SecurityPanelSidebar.ts +1 -3
  69. package/front_end/panels/settings/KeybindsSettingsTab.ts +1 -1
  70. package/front_end/panels/sources/CSSPlugin.ts +1 -1
  71. package/front_end/panels/sources/DebuggerPlugin.ts +2 -2
  72. package/front_end/panels/sources/NavigatorView.ts +1 -1
  73. package/front_end/panels/sources/SourcesSearchScope.ts +1 -1
  74. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +10 -2
  75. package/front_end/panels/timeline/TimelineFlameChartView.ts +1 -1
  76. package/front_end/panels/timeline/TimelinePanel.ts +7 -7
  77. package/front_end/panels/timeline/TimelineUIUtils.ts +3 -1
  78. package/front_end/panels/timeline/enable-easter-egg.js +1 -1
  79. package/front_end/panels/timeline/utils/Treemap.ts +1 -1
  80. package/front_end/third_party/chromium/README.chromium +1 -1
  81. package/front_end/third_party/puppeteer/README.chromium +2 -2
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.d.ts +66 -0
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.d.ts.map +1 -0
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.js +57 -0
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.js.map +1 -0
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.d.ts +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.d.ts.map +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +2 -2
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.d.ts +1 -0
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.d.ts.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.js +1 -0
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +1 -6
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +0 -4
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +18 -23
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +2 -0
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +16 -0
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.d.ts +4 -62
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.js +9 -73
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Frame.d.ts +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Frame.d.ts.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Frame.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -3
  117. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.d.ts +8 -1
  119. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.d.ts.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.js +11 -1
  121. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.js.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  124. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  125. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  127. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +9 -10
  130. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +80 -81
  131. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.d.ts +66 -0
  132. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.d.ts.map +1 -0
  133. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.js +52 -0
  134. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.js.map +1 -0
  135. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.d.ts +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.d.ts.map +1 -1
  137. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +2 -2
  139. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.d.ts +1 -0
  142. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.d.ts.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.js +1 -0
  144. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.js.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  146. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +1 -6
  147. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +0 -4
  149. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +18 -23
  151. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +2 -0
  153. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +16 -0
  155. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  156. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.d.ts +4 -62
  157. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.d.ts.map +1 -1
  158. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js +6 -69
  159. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js.map +1 -1
  160. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Frame.d.ts +1 -1
  161. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Frame.d.ts.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Frame.js.map +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -1
  164. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  165. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +3 -3
  166. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  167. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.d.ts +8 -1
  168. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.d.ts.map +1 -1
  169. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.js +11 -1
  170. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.js.map +1 -1
  171. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  172. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  173. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  174. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  175. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  176. package/front_end/third_party/puppeteer/package/lib/types.d.ts +9 -10
  177. package/front_end/third_party/puppeteer/package/package.json +3 -3
  178. package/front_end/third_party/puppeteer/package/src/api/DeviceRequestPrompt.ts +79 -0
  179. package/front_end/third_party/puppeteer/package/src/api/Frame.ts +1 -1
  180. package/front_end/third_party/puppeteer/package/src/api/Page.ts +2 -2
  181. package/front_end/third_party/puppeteer/package/src/api/api.ts +1 -0
  182. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +1 -9
  183. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +21 -31
  184. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +18 -0
  185. package/front_end/third_party/puppeteer/package/src/cdp/DeviceRequestPrompt.ts +6 -72
  186. package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +2 -4
  187. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +7 -2
  188. package/front_end/third_party/puppeteer/package/src/common/ConsoleMessage.ts +14 -0
  189. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  190. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  191. package/front_end/third_party/puppeteer/puppeteer-tsconfig.json +1 -0
  192. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +4 -0
  193. package/front_end/ui/components/text_editor/javascript.ts +1 -1
  194. package/front_end/ui/legacy/ListWidget.ts +51 -18
  195. package/front_end/ui/legacy/ReportView.ts +1 -1
  196. package/front_end/ui/legacy/TabbedPane.ts +3 -3
  197. package/front_end/ui/legacy/Treeoutline.ts +1 -1
  198. package/front_end/ui/legacy/components/color_picker/ContrastInfo.ts +1 -1
  199. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +3 -2
  200. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +87 -111
  201. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +1 -2
  202. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +40 -11
  203. package/front_end/ui/legacy/components/utils/jsUtils.css +28 -0
  204. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  205. package/front_end/ui/visual_logging/LoggingConfig.ts +2 -1
  206. package/inspector_overlay/tool_window_controls.ts +4 -1
  207. package/mcp/mcp.ts +1 -1
  208. package/package.json +2 -3
  209. package/front_end/core/common/Worker.ts +0 -60
  210. package/front_end/panels/application/components/StackTrace.ts +0 -238
  211. package/front_end/panels/application/components/stackTraceLinkButton.css +0 -16
  212. package/front_end/panels/application/components/stackTraceRow.css +0 -50
@@ -12,6 +12,7 @@ import * as Root from '../../core/root/root.js';
12
12
  import * as SDK from '../../core/sdk/sdk.js';
13
13
  import * as Protocol from '../../generated/protocol.js';
14
14
  import * as Bindings from '../../models/bindings/bindings.js';
15
+ import type * as StackTrace from '../../models/stack_trace/stack_trace.js';
15
16
  import * as Workspace from '../../models/workspace/workspace.js';
16
17
  import * as PanelCommon from '../../panels/common/common.js';
17
18
  import * as NetworkForward from '../../panels/network/forward/forward.js';
@@ -21,14 +22,13 @@ import type * as ExpandableList from '../../ui/components/expandable_list/expand
21
22
  import type * as ReportView from '../../ui/components/report_view/report_view.js';
22
23
  import * as Components from '../../ui/legacy/components/utils/utils.js';
23
24
  import * as UI from '../../ui/legacy/legacy.js';
24
- import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
25
+ import {html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
25
26
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
26
27
 
27
28
  import * as ApplicationComponents from './components/components.js';
28
29
  import frameDetailsReportViewStyles from './frameDetailsReportView.css.js';
29
30
  import {OriginTrialTreeView} from './OriginTrialTreeView.js';
30
31
 
31
- const {until} = Directives;
32
32
  const {widgetConfig} = UI.Widget;
33
33
 
34
34
  const UIStrings = {
@@ -270,12 +270,14 @@ export interface FrameDetailsReportViewData {
270
270
  interface FrameDetailsViewInput {
271
271
  frame: SDK.ResourceTreeModel.ResourceTreeFrame;
272
272
  target: SDK.Target.Target|null;
273
+ creationStackTrace: StackTrace.StackTrace.StackTrace|null;
274
+ creationTarget: SDK.Target.Target|null;
273
275
  adScriptAncestry: Protocol.Page.AdScriptAncestry|null;
274
- linkTargetDOMNode?: Promise<SDK.DOMModel.DOMNode|null>;
275
- permissionsPolicies: Promise<Protocol.Page.PermissionsPolicyFeatureState[]|null>|null;
276
+ linkTargetDOMNode: SDK.DOMModel.DOMNode|null;
277
+ permissionsPolicies: Protocol.Page.PermissionsPolicyFeatureState[]|null;
276
278
  protocolMonitorExperimentEnabled: boolean;
277
279
  trials: Protocol.Page.OriginTrial[]|null;
278
- securityIsolationInfo?: Promise<Protocol.Network.SecurityIsolationStatus|null>;
280
+ securityIsolationInfo: Protocol.Network.SecurityIsolationStatus|null;
279
281
  onRevealInNetwork?: () => void;
280
282
  onRevealInSources: () => void;
281
283
  }
@@ -295,11 +297,12 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
295
297
  ${renderIsolationSection(input)}
296
298
  ${renderApiAvailabilitySection(input.frame)}
297
299
  ${renderOriginTrial(input.trials)}
298
- ${until(input.permissionsPolicies?.then?.(policies =>
300
+ ${input.permissionsPolicies ?
299
301
  html`
300
- <devtools-resources-permissions-policy-section .data=${{policies, showDetails: false} as ApplicationComponents.PermissionsPolicySection.PermissionsPolicySectionData}>
302
+ <devtools-resources-permissions-policy-section
303
+ .data=${{policies: input.permissionsPolicies, showDetails: false} as ApplicationComponents.PermissionsPolicySection.PermissionsPolicySectionData}>
301
304
  </devtools-resources-permissions-policy-section>
302
- `), nothing)}
305
+ ` : nothing}
303
306
  ${input.protocolMonitorExperimentEnabled ? renderAdditionalInfoSection(input.frame) : nothing}
304
307
  </devtools-report>
305
308
  `, target);
@@ -337,6 +340,7 @@ function renderDocumentSection(input: FrameDetailsViewInput): LitTemplate {
337
340
  return nothing;
338
341
  }
339
342
 
343
+ // clang-format off
340
344
  return html`
341
345
  <devtools-report-section-header>${i18nString(UIStrings.document)}</devtools-report-section-header>
342
346
  <devtools-report-key>${i18nString(UIStrings.url)}</devtools-report-key>
@@ -349,12 +353,12 @@ function renderDocumentSection(input: FrameDetailsViewInput): LitTemplate {
349
353
  </devtools-report-value>
350
354
  ${maybeRenderUnreachableURL(input.frame?.unreachableUrl())}
351
355
  ${maybeRenderOrigin(input.frame?.securityOrigin)}
352
- ${until(input.linkTargetDOMNode?.then?.(value => renderOwnerElement(value)), nothing)}
353
- ${maybeRenderCreationStacktrace(input.frame.getCreationStackTraceData())}
356
+ ${renderOwnerElement(input.linkTargetDOMNode)}
357
+ ${maybeRenderCreationStacktrace(input.creationStackTrace, input.creationTarget)}
354
358
  ${maybeRenderAdStatus(input.frame?.adFrameType(), input.frame?.adFrameStatus())}
355
359
  ${maybeRenderCreatorAdScriptAncestry(input.frame?.adFrameType(), input.target, input.adScriptAncestry)}
356
- <devtools-report-divider></devtools-report-divider>
357
- `;
360
+ <devtools-report-divider></devtools-report-divider>`;
361
+ // clang-format on
358
362
  }
359
363
 
360
364
  function renderSourcesLinkForURL(onRevealInSources: () => void): LitTemplate {
@@ -444,22 +448,16 @@ function renderOwnerElement(linkTargetDOMNode: SDK.DOMModel.DOMNode|null): LitTe
444
448
  }
445
449
 
446
450
  function maybeRenderCreationStacktrace(
447
- creationStackTraceData:
448
- {creationStackTrace: Protocol.Runtime.StackTrace|null, creationStackTraceTarget: SDK.Target.Target}|
449
- null): LitTemplate {
450
- if (creationStackTraceData?.creationStackTrace) {
451
+ stackTrace: StackTrace.StackTrace.StackTrace|null, target: SDK.Target.Target|null): LitTemplate {
452
+ if (stackTrace && target) {
451
453
  // Disabled until https://crbug.com/1079231 is fixed.
452
454
  // clang-format off
453
455
  return html`
454
456
  <devtools-report-key title=${i18nString(UIStrings.creationStackTraceExplanation)}>${
455
457
  i18nString(UIStrings.creationStackTrace)}</devtools-report-key>
456
458
  <devtools-report-value jslog=${VisualLogging.section('frame-creation-stack-trace')}>
457
- <devtools-widget .widgetConfig=${widgetConfig(
458
- ApplicationComponents.StackTrace.StackTrace, { data: {
459
- creationStackTraceData,
460
- buildStackTraceRows: Components.JSPresentationUtils.buildStackTraceRowsForLegacyRuntimeStackTrace }
461
- }
462
- )}>
459
+ <devtools-widget .widgetConfig=${UI.Widget.widgetConfig(
460
+ Components.JSPresentationUtils.StackTracePreviewContent, {target, stackTrace, options: {expandable: true}})}>
463
461
  </devtools-widget>
464
462
  </devtools-report-value>
465
463
  `;
@@ -569,7 +567,7 @@ function renderIsolationSection(input: FrameDetailsViewInput): LitTemplate {
569
567
  <devtools-report-value>
570
568
  ${input.frame.isCrossOriginIsolated() ? i18nString(UIStrings.yes) : i18nString(UIStrings.no)}
571
569
  </devtools-report-value>
572
- ${until(input.securityIsolationInfo?.then?.(value => maybeRenderCoopCoepCSPStatus(value)), nothing)}
570
+ ${maybeRenderCoopCoepCSPStatus(input.securityIsolationInfo)}
573
571
  <devtools-report-divider></devtools-report-divider>
574
572
  `;
575
573
  }
@@ -597,7 +595,7 @@ function getSecureContextExplanation(frame: SDK.ResourceTreeModel.ResourceTreeFr
597
595
  return null;
598
596
  }
599
597
 
600
- async function maybeRenderCoopCoepCSPStatus(info: Protocol.Network.SecurityIsolationStatus|null): Promise<LitTemplate> {
598
+ function maybeRenderCoopCoepCSPStatus(info: Protocol.Network.SecurityIsolationStatus|null): LitTemplate {
601
599
  if (info) {
602
600
  return html`
603
601
  ${
@@ -845,8 +843,13 @@ function renderAdditionalInfoSection(frame: SDK.ResourceTreeModel.ResourceTreeFr
845
843
  export class FrameDetailsReportView extends UI.Widget.Widget {
846
844
  #frame?: SDK.ResourceTreeModel.ResourceTreeFrame;
847
845
  #target: SDK.Target.Target|null = null;
846
+ #creationStackTrace: StackTrace.StackTrace.StackTrace|null = null;
847
+ #creationTarget: SDK.Target.Target|null = null;
848
+ #securityIsolationInfo: Protocol.Network.SecurityIsolationStatus|null = null;
849
+ #linkTargetDOMNode: SDK.DOMModel.DOMNode|null = null;
850
+ #trials: Protocol.Page.OriginTrial[]|null = null;
848
851
  #protocolMonitorExperimentEnabled = false;
849
- #permissionsPolicies: Promise<Protocol.Page.PermissionsPolicyFeatureState[]|null>|null = null;
852
+ #permissionsPolicies: Protocol.Page.PermissionsPolicyFeatureState[]|null = null;
850
853
  #linkifier = new Components.Linkifier.Linkifier();
851
854
  #adScriptAncestry: Protocol.Page.AdScriptAncestry|null = null;
852
855
  #view: View;
@@ -859,6 +862,34 @@ export class FrameDetailsReportView extends UI.Widget.Widget {
859
862
 
860
863
  set frame(frame: SDK.ResourceTreeModel.ResourceTreeFrame) {
861
864
  this.#frame = frame;
865
+ void this.#frame.getPermissionsPolicyState().then(permissionsPolicies => {
866
+ this.#permissionsPolicies = permissionsPolicies;
867
+ this.requestUpdate();
868
+ });
869
+ const {creationStackTrace: rawCreationStackTrace, creationStackTraceTarget: creationTarget} =
870
+ frame.getCreationStackTraceData();
871
+ this.#creationTarget = creationTarget;
872
+ if (rawCreationStackTrace) {
873
+ void Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
874
+ .createStackTraceFromProtocolRuntime(rawCreationStackTrace, creationTarget)
875
+ .then(creationStackTrace => {
876
+ this.#creationStackTrace = creationStackTrace;
877
+ this.requestUpdate();
878
+ });
879
+ }
880
+ const networkManager = frame.resourceTreeModel().target().model(SDK.NetworkManager.NetworkManager);
881
+ void networkManager?.getSecurityIsolationStatus(frame.id).then(securityIsolationInfo => {
882
+ this.#securityIsolationInfo = securityIsolationInfo;
883
+ this.requestUpdate();
884
+ });
885
+ void frame.getOwnerDOMNodeOrDocument().then(linkTargetDOMNode => {
886
+ this.#linkTargetDOMNode = linkTargetDOMNode;
887
+ this.requestUpdate();
888
+ });
889
+ void frame.getOriginTrials().then(trials => {
890
+ this.#trials = trials;
891
+ this.requestUpdate();
892
+ });
862
893
  this.requestUpdate();
863
894
  }
864
895
 
@@ -882,27 +913,24 @@ export class FrameDetailsReportView extends UI.Widget.Widget {
882
913
  this.#target = debuggerModel?.target() ?? null;
883
914
  }
884
915
 
885
- if (!this.#permissionsPolicies && this.#frame) {
886
- this.#permissionsPolicies = this.#frame.getPermissionsPolicyState();
887
- }
888
916
  const frame = this.#frame;
889
917
  if (!frame) {
890
918
  return;
891
919
  }
892
- const networkManager = frame.resourceTreeModel().target().model(SDK.NetworkManager.NetworkManager);
893
- const securityIsolationInfo = networkManager?.getSecurityIsolationStatus(frame.id);
894
- const linkTargetDOMNode = frame.getOwnerDOMNodeOrDocument();
895
920
  const frameRequest = frame.resourceForURL(frame.url)?.request;
921
+
896
922
  const input = {
897
923
  frame,
898
924
  target: this.#target,
925
+ creationStackTrace: this.#creationStackTrace,
926
+ creationTarget: this.#creationTarget,
899
927
  protocolMonitorExperimentEnabled: this.#protocolMonitorExperimentEnabled,
900
928
  permissionsPolicies: this.#permissionsPolicies,
901
929
  adScriptAncestry: this.#adScriptAncestry,
902
930
  linkifier: this.#linkifier,
903
- linkTargetDOMNode,
904
- trials: await frame.getOriginTrials(),
905
- securityIsolationInfo,
931
+ linkTargetDOMNode: this.#linkTargetDOMNode,
932
+ trials: this.#trials,
933
+ securityIsolationInfo: this.#securityIsolationInfo,
906
934
  onRevealInNetwork: frameRequest ?
907
935
  () => {
908
936
  const requestLocation = NetworkForward.UIRequestLocation.UIRequestLocation.tab(
@@ -410,7 +410,7 @@ export class ServiceWorkerCacheView extends UI.View.SimpleView {
410
410
  }
411
411
 
412
412
  // It is possible that table selection changes before the preview opens.
413
- if (this.dataGrid?.selectedNode && request === this.dataGrid.selectedNode.data) {
413
+ if (request === this.dataGrid?.selectedNode?.data) {
414
414
  this.showPreview(preview);
415
415
  }
416
416
  }
@@ -12,7 +12,6 @@ import * as ReportsGrid from './ReportsGrid.js';
12
12
  import * as ServiceWorkerRouterView from './ServiceWorkerRouterView.js';
13
13
  import * as SharedStorageAccessGrid from './SharedStorageAccessGrid.js';
14
14
  import * as SharedStorageMetadataView from './SharedStorageMetadataView.js';
15
- import * as StackTrace from './StackTrace.js';
16
15
  import * as StorageMetadataView from './StorageMetadataView.js';
17
16
  import * as TrustTokensView from './TrustTokensView.js';
18
17
 
@@ -27,7 +26,6 @@ export {
27
26
  ServiceWorkerRouterView,
28
27
  SharedStorageAccessGrid,
29
28
  SharedStorageMetadataView,
30
- StackTrace,
31
29
  StorageMetadataView,
32
30
  TrustTokensView,
33
31
  };
@@ -94,6 +94,14 @@ const DATA_USAGE_URL = 'https://developer.chrome.com/docs/devtools/ai-assistance
94
94
  const EXPLAIN_TEASER_ACTION_ID = 'explain.console-message.teaser';
95
95
  const SLOW_GENERATION_CUTOFF_MILLISECONDS = 3500;
96
96
 
97
+ const enum State {
98
+ READY = 'ready',
99
+ GENERATING = 'generating', // Before receiving first chunk
100
+ PARTIAL_TEASER = 'partial-teaser', // After receiving first chunk
101
+ TEASER = 'teaser',
102
+ ERROR = 'error',
103
+ }
104
+
97
105
  interface ViewInput {
98
106
  onTellMeMoreClick: (event: Event) => void;
99
107
  // If multiple ConsoleInsightTeasers exist, each one needs a unique id. Otherwise showing and
@@ -105,7 +113,121 @@ interface ViewInput {
105
113
  dontShowChanged: (e: Event) => void;
106
114
  hasTellMeMoreButton: boolean;
107
115
  isSlowGeneration: boolean;
108
- isError: boolean;
116
+ state: State;
117
+ }
118
+
119
+ function renderGenerating(input: ViewInput): Lit.TemplateResult {
120
+ // clang-format off
121
+ return html`
122
+ <div class="teaser-tooltip-container">
123
+ <div class="response-container">
124
+ <h2>${input.isSlowGeneration ?
125
+ lockedString(UIStringsNotTranslate.summarizingTakesABitLonger) :
126
+ lockedString(UIStringsNotTranslate.summarizing)
127
+ }</h2>
128
+ <div
129
+ role="presentation"
130
+ aria-label=${lockedString(UIStringsNotTranslate.loading)}
131
+ class="loader"
132
+ style="clip-path: url(${'#clipPath-' + input.uuid});"
133
+ >
134
+ <svg width="100%" height="58">
135
+ <defs>
136
+ <clipPath id=${'clipPath-' + input.uuid}>
137
+ <rect x="0" y="0" width="100%" height="12" rx="8"></rect>
138
+ <rect x="0" y="20" width="100%" height="12" rx="8"></rect>
139
+ <rect x="0" y="40" width="100%" height="12" rx="8"></rect>
140
+ </clipPath>
141
+ </defs>
142
+ </svg>
143
+ </div>
144
+ </div>
145
+ ${renderFooter(input)}
146
+ </div>
147
+ `;
148
+ // clang-format on
149
+ }
150
+
151
+ function renderError(input: ViewInput): Lit.TemplateResult {
152
+ // clang-format off
153
+ return html`
154
+ <div class="teaser-tooltip-container">
155
+ <h2>${lockedString(UIStringsNotTranslate.summaryNotAvailable)}</h2>
156
+ ${renderFooter(input)}
157
+ </div>
158
+ `;
159
+ // clang-format on
160
+ }
161
+
162
+ function renderDontShowCheckbox(input: ViewInput): Lit.TemplateResult {
163
+ // clang-format off
164
+ return html`
165
+ <devtools-checkbox
166
+ aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
167
+ @change=${input.dontShowChanged}
168
+ jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
169
+ ${lockedString(UIStringsNotTranslate.dontShow)}
170
+ </devtools-checkbox>
171
+ `;
172
+ // clang-format on
173
+ }
174
+
175
+ function renderFooter(input: ViewInput): Lit.TemplateResult {
176
+ // clang-format off
177
+ return html`
178
+ <div class="tooltip-footer">
179
+ ${input.hasTellMeMoreButton ? html`
180
+ <devtools-button
181
+ title=${lockedString(UIStringsNotTranslate.tellMeMore)}
182
+ .jslogContext=${'insights-teaser-tell-me-more'}
183
+ .variant=${Buttons.Button.Variant.PRIMARY}
184
+ @click=${input.onTellMeMoreClick}
185
+ >
186
+ <devtools-icon class="lightbulb-icon" name="lightbulb-spark"></devtools-icon>
187
+ ${lockedString(UIStringsNotTranslate.tellMeMore)}
188
+ </devtools-button>
189
+ ` : Lit.nothing}
190
+ <devtools-button
191
+ .iconName=${'info'}
192
+ .variant=${Buttons.Button.Variant.ICON}
193
+ aria-details=${'teaser-info-tooltip-' + input.uuid}
194
+ .accessibleLabel=${lockedString(UIStringsNotTranslate.learnDataUsage)}
195
+ ></devtools-button>
196
+ <devtools-tooltip
197
+ id=${'teaser-info-tooltip-' + input.uuid}
198
+ variant="rich"
199
+ jslogContext="teaser-info-tooltip"
200
+ trigger="both"
201
+ hover-delay=500
202
+ >
203
+ <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
204
+ <div class="learn-more">
205
+ <x-link
206
+ class="devtools-link"
207
+ title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
208
+ href=${DATA_USAGE_URL}
209
+ jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
210
+ >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
211
+ </div>
212
+ </devtools-tooltip>
213
+ ${renderDontShowCheckbox(input)}
214
+ </div>
215
+ `;
216
+ // clang-format on
217
+ }
218
+
219
+ function renderTeaser(input: ViewInput): Lit.TemplateResult {
220
+ // clang-format off
221
+ return html`
222
+ <div class="teaser-tooltip-container">
223
+ <div class="response-container">
224
+ <h2>${input.headerText}</h2>
225
+ <div class="main-text">${input.mainText}</div>
226
+ </div>
227
+ ${renderFooter(input)}
228
+ </div>
229
+ `;
230
+ // clang-format on
109
231
  }
110
232
 
111
233
  export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
@@ -114,7 +236,6 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
114
236
  return;
115
237
  }
116
238
 
117
- const showPlaceholder = !Boolean(input.mainText);
118
239
  // clang-format off
119
240
  render(html`
120
241
  <style>${consoleInsightTeaserStyles}</style>
@@ -126,83 +247,18 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
126
247
  prefer-span-left
127
248
  jslogContext="console-insight-teaser"
128
249
  >
129
- <div class="teaser-tooltip-container">
130
- ${input.isError ? html`
131
- <h2>${lockedString(UIStringsNotTranslate.summaryNotAvailable)}</h2>
132
- ` :
133
- showPlaceholder ? html`
134
- <div class="response-container">
135
- <h2>${input.isSlowGeneration ?
136
- lockedString(UIStringsNotTranslate.summarizingTakesABitLonger) :
137
- lockedString(UIStringsNotTranslate.summarizing)
138
- }</h2>
139
- <div
140
- role="presentation"
141
- aria-label=${lockedString(UIStringsNotTranslate.loading)}
142
- class="loader"
143
- style="clip-path: url(${'#clipPath-' + input.uuid});"
144
- >
145
- <svg width="100%" height="58">
146
- <defs>
147
- <clipPath id=${'clipPath-' + input.uuid}>
148
- <rect x="0" y="0" width="100%" height="12" rx="8"></rect>
149
- <rect x="0" y="20" width="100%" height="12" rx="8"></rect>
150
- <rect x="0" y="40" width="100%" height="12" rx="8"></rect>
151
- </clipPath>
152
- </defs>
153
- </svg>
154
- </div>
155
- </div>
156
- ` : html`
157
- <div class="response-container">
158
- <h2>${input.headerText}</h2>
159
- <div class="main-text">${input.mainText}</div>
160
- </div>
161
- `
250
+ ${(() => {
251
+ switch (input.state) {
252
+ case State.READY:
253
+ case State.GENERATING:
254
+ return renderGenerating(input);
255
+ case State.ERROR:
256
+ return renderError(input);
257
+ case State.PARTIAL_TEASER:
258
+ case State.TEASER:
259
+ return renderTeaser(input);
162
260
  }
163
- <div class="tooltip-footer">
164
- ${input.hasTellMeMoreButton ? html`
165
- <devtools-button
166
- title=${lockedString(UIStringsNotTranslate.tellMeMore)}
167
- .jslogContext=${'insights-teaser-tell-me-more'}
168
- .variant=${Buttons.Button.Variant.PRIMARY}
169
- @click=${input.onTellMeMoreClick}
170
- >
171
- <devtools-icon class="lightbulb-icon" name="lightbulb-spark"></devtools-icon>
172
- ${lockedString(UIStringsNotTranslate.tellMeMore)}
173
- </devtools-button>
174
- ` : Lit.nothing}
175
- <devtools-button
176
- .iconName=${'info'}
177
- .variant=${Buttons.Button.Variant.ICON}
178
- aria-details=${'teaser-info-tooltip-' + input.uuid}
179
- .accessibleLabel=${lockedString(UIStringsNotTranslate.learnDataUsage)}
180
- ></devtools-button>
181
- <devtools-tooltip
182
- id=${'teaser-info-tooltip-' + input.uuid}
183
- variant="rich"
184
- jslogContext="teaser-info-tooltip"
185
- trigger="both"
186
- hover-delay=500
187
- >
188
- <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
189
- <div class="learn-more">
190
- <x-link
191
- class="devtools-link"
192
- title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
193
- href=${DATA_USAGE_URL}
194
- jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
195
- >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
196
- </div>
197
- </devtools-tooltip>
198
- <devtools-checkbox
199
- aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
200
- @change=${input.dontShowChanged}
201
- jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
202
- ${lockedString(UIStringsNotTranslate.dontShow)}
203
- </devtools-checkbox>
204
- </div>
205
- </div>
261
+ })()}
206
262
  </devtools-tooltip>
207
263
  `, target);
208
264
  // clang-format on
@@ -213,8 +269,7 @@ export type View = typeof DEFAULT_VIEW;
213
269
  export class ConsoleInsightTeaser extends UI.Widget.Widget {
214
270
  #view: View;
215
271
  #uuid: string;
216
- #isGenerating = false;
217
- #builtInAi: AiAssistanceModel.BuiltInAi.BuiltInAi|undefined;
272
+ #builtInAi: AiAssistanceModel.BuiltInAi.BuiltInAi;
218
273
  #promptBuilder: PromptBuilder;
219
274
  #headerText = '';
220
275
  #mainText = '';
@@ -223,9 +278,9 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
223
278
  #abortController: null|AbortController = null;
224
279
  #isSlow = false;
225
280
  #timeoutId: ReturnType<typeof setTimeout>|null = null;
226
- #isError = false;
227
281
  #aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
228
282
  #boundOnAidaAvailabilityChange: () => Promise<void>;
283
+ #state: State;
229
284
 
230
285
  constructor(uuid: string, consoleViewMessage: ConsoleViewMessage, element?: HTMLElement, view?: View) {
231
286
  super(element);
@@ -234,6 +289,8 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
234
289
  this.#promptBuilder = new PromptBuilder(consoleViewMessage);
235
290
  this.#consoleViewMessage = consoleViewMessage;
236
291
  this.#boundOnAidaAvailabilityChange = this.#onAidaAvailabilityChange.bind(this);
292
+ this.#builtInAi = AiAssistanceModel.BuiltInAi.BuiltInAi.instance();
293
+ this.#state = State.READY;
237
294
  this.requestUpdate();
238
295
  }
239
296
 
@@ -316,10 +373,24 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
316
373
  }
317
374
 
318
375
  maybeGenerateTeaser(): void {
319
- this.requestUpdate();
320
- if (!this.#isInactive && !this.#isGenerating && !Boolean(this.#mainText) &&
321
- Common.Settings.Settings.instance().moduleSetting('console-insight-teasers-enabled').get()) {
322
- void this.#generateTeaserText();
376
+ switch (this.#state) {
377
+ case State.READY:
378
+ if (!this.#isInactive &&
379
+ Common.Settings.Settings.instance().moduleSetting('console-insight-teasers-enabled').get()) {
380
+ void this.#generateTeaserText();
381
+ }
382
+ this.requestUpdate();
383
+ return;
384
+ case State.GENERATING:
385
+ console.error('Trying trigger teaser generation when state is "GENERATING"');
386
+ return;
387
+ case State.PARTIAL_TEASER:
388
+ console.error('Trying trigger teaser generation when state is "PARTIAL_TEASER"');
389
+ return;
390
+ // These are terminal states. No need to update anything.
391
+ case State.TEASER:
392
+ case State.ERROR:
393
+ return;
323
394
  }
324
395
  }
325
396
 
@@ -327,11 +398,11 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
327
398
  if (this.#abortController) {
328
399
  this.#abortController.abort();
329
400
  }
330
- if (this.#isGenerating) {
401
+ if (this.#state === State.GENERATING || this.#state === State.PARTIAL_TEASER) {
331
402
  this.#mainText = '';
403
+ this.#state = State.READY;
332
404
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightTeaserGenerationAborted);
333
405
  }
334
- this.#isGenerating = false;
335
406
  if (this.#timeoutId) {
336
407
  clearTimeout(this.#timeoutId);
337
408
  }
@@ -352,7 +423,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
352
423
 
353
424
  async #generateTeaserText(): Promise<void> {
354
425
  this.#headerText = this.#consoleViewMessage.toMessageTextString().substring(0, 70);
355
- this.#isGenerating = true;
426
+ this.#state = State.GENERATING;
356
427
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightTeaserGenerationStarted);
357
428
  this.#timeoutId = setTimeout(this.#setSlow.bind(this), SLOW_GENERATION_CUTOFF_MILLISECONDS);
358
429
  const startTime = performance.now();
@@ -362,6 +433,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
362
433
  for await (const chunk of this.#getOnDeviceInsight()) {
363
434
  teaserText += chunk;
364
435
  this.#mainText = teaserText;
436
+ this.#state = State.PARTIAL_TEASER;
365
437
  this.requestUpdate();
366
438
  if (!firstChunkReceived) {
367
439
  firstChunkReceived = true;
@@ -370,12 +442,13 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
370
442
  }
371
443
  } catch (err) {
372
444
  // Ignore `AbortError` errors, which are thrown on mouse leave.
373
- if (err.name !== 'AbortError') {
445
+ if (err.name === 'AbortError') {
446
+ this.#state = State.READY;
447
+ } else {
374
448
  console.error(err.name, err.message);
375
- this.#isError = true;
449
+ this.#state = State.ERROR;
376
450
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightTeaserGenerationErrored);
377
451
  }
378
- this.#isGenerating = false;
379
452
  clearTimeout(this.#timeoutId);
380
453
  this.requestUpdate();
381
454
  return;
@@ -383,7 +456,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
383
456
 
384
457
  clearTimeout(this.#timeoutId);
385
458
  Host.userMetrics.consoleInsightTeaserGenerated(performance.now() - startTime);
386
- this.#isGenerating = false;
459
+ this.#state = State.TEASER;
387
460
  this.#mainText = teaserText;
388
461
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightTeaserGenerationCompleted);
389
462
  this.requestUpdate();
@@ -391,13 +464,6 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
391
464
 
392
465
  async * #getOnDeviceInsight(): AsyncGenerator<string> {
393
466
  const {prompt} = await this.#promptBuilder.buildPrompt();
394
- if (!this.#builtInAi) {
395
- this.#builtInAi = await AiAssistanceModel.BuiltInAi.BuiltInAi.instance();
396
- if (!this.#builtInAi) {
397
- this.#isInactive = true;
398
- throw new Error('Cannot instantiate BuiltInAi');
399
- }
400
- }
401
467
  this.#abortController = new AbortController();
402
468
  const stream = this.#builtInAi.getConsoleInsight(prompt, this.#abortController);
403
469
  for await (const chunk of stream) {
@@ -436,7 +502,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
436
502
  dontShowChanged: this.#dontShowChanged.bind(this),
437
503
  hasTellMeMoreButton: this.#hasTellMeMoreButton(),
438
504
  isSlowGeneration: this.#isSlow,
439
- isError: this.#isError,
505
+ state: this.#state,
440
506
  },
441
507
  undefined, this.contentElement);
442
508
  }
@@ -285,7 +285,7 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
285
285
  if (preview.deepTextContent() !== TextEditor.Config.contentIncludingHint(this.editor.editor).trim()) {
286
286
  this.innerPreviewElement.appendChild(preview);
287
287
  }
288
- if (result && 'object' in result && result.object && result.object.subtype === 'node') {
288
+ if (result && 'object' in result && result.object?.subtype === 'node') {
289
289
  this.highlightingNode = true;
290
290
  SDK.OverlayModel.OverlayModel.highlightObjectAsDOMNode(result.object);
291
291
  } else if (this.highlightingNode) {