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
@@ -365,10 +365,10 @@ function toolbarView(input: ToolbarViewInput): Lit.LitTemplate {
365
365
  <devtools-toolbar class="freestyler-right-toolbar" role="presentation">
366
366
  <x-link
367
367
  class="toolbar-feedback-link devtools-link"
368
- title=${UIStrings.sendFeedback}
368
+ title=${i18nString(UIStrings.sendFeedback)}
369
369
  href=${AI_ASSISTANCE_SEND_FEEDBACK}
370
370
  jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('freestyler.send-feedback')}
371
- >${UIStrings.sendFeedback}</x-link>
371
+ >${i18nString(UIStrings.sendFeedback)}</x-link>
372
372
  <div class="toolbar-divider"></div>
373
373
  <devtools-button
374
374
  title=${i18nString(UIStrings.help)}
@@ -461,26 +461,6 @@ function createPerformanceTraceContext(focus: AiAssistanceModel.AIContext.AgentF
461
461
  return new AiAssistanceModel.PerformanceAgent.PerformanceTraceContext(focus);
462
462
  }
463
463
 
464
- function agentToConversationType(agent: AiAssistanceModel.AiAgent.AiAgent<unknown>):
465
- AiAssistanceModel.AiHistoryStorage.ConversationType {
466
- if (agent instanceof AiAssistanceModel.StylingAgent.StylingAgent) {
467
- return AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING;
468
- }
469
-
470
- if (agent instanceof AiAssistanceModel.NetworkAgent.NetworkAgent) {
471
- return AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK;
472
- }
473
- if (agent instanceof AiAssistanceModel.FileAgent.FileAgent) {
474
- return AiAssistanceModel.AiHistoryStorage.ConversationType.FILE;
475
- }
476
-
477
- if (agent instanceof AiAssistanceModel.PerformanceAgent.PerformanceAgent) {
478
- return AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE;
479
- }
480
-
481
- throw new Error('Provided agent does not have a corresponding conversation type');
482
- }
483
-
484
464
  let panelInstance: AiAssistancePanel;
485
465
  export class AiAssistancePanel extends UI.Panel.Panel {
486
466
  static panelName = 'freestyler';
@@ -494,7 +474,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
494
474
  #changeManager = new AiAssistanceModel.ChangeManager.ChangeManager();
495
475
  #mutex = new Common.Mutex.Mutex();
496
476
 
497
- #conversationAgent?: AiAssistanceModel.AiAgent.AiAgent<unknown>;
498
477
  #conversation?: AiAssistanceModel.AiConversation.AiConversation;
499
478
 
500
479
  #selectedFile: AiAssistanceModel.FileAgent.FileContext|null = null;
@@ -504,10 +483,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
504
483
 
505
484
  // Messages displayed in the `ChatView` component.
506
485
  #messages: ChatMessage[] = [];
507
- // Indicates whether the new conversation context is blocked due to cross-origin restrictions.
508
- // This happens when the conversation's context has a different
509
- // origin than the selected context.
510
- #blockedByCrossOrigin = false;
486
+
511
487
  // Whether the UI should show loading or not.
512
488
  #isLoading = false;
513
489
  // Selected conversation context. The reason we keep this as a
@@ -527,7 +503,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
527
503
  // Used to disable send button when there is not text input.
528
504
  #isTextInputEmpty = true;
529
505
  #timelinePanelInstance: TimelinePanel.TimelinePanel.TimelinePanel|null = null;
530
- #conversationHandler: AiAssistanceModel.ConversationHandler.ConversationHandler;
531
506
  #runAbortController = new AbortController();
532
507
 
533
508
  constructor(private view: View = defaultView, {aidaClient, aidaAvailability, syncInfo}: {
@@ -545,8 +520,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
545
520
  accountImage: syncInfo.accountImage,
546
521
  accountFullName: syncInfo.accountFullName,
547
522
  };
548
- this.#conversationHandler = AiAssistanceModel.ConversationHandler.ConversationHandler.instance(
549
- {aidaClient: this.#aidaClient, aidaAvailability});
550
523
 
551
524
  if (UI.ActionRegistry.ActionRegistry.instance().hasAction('elements.toggle-element-search')) {
552
525
  this.#toggleSearchElementAction =
@@ -569,7 +542,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
569
542
  };
570
543
  }
571
544
 
572
- if (this.#conversation?.type) {
545
+ if (this.#conversation) {
573
546
  const emptyStateSuggestions = await getEmptyStateSuggestions(this.#selectedContext, this.#conversation);
574
547
  const markdownRenderer = getMarkdownRenderer(this.#selectedContext, this.#conversation);
575
548
  return {
@@ -683,7 +656,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
683
656
  const isSourcesPanelVisible = viewManager.isViewVisible('sources');
684
657
  const isPerformancePanelVisible = viewManager.isViewVisible('timeline');
685
658
 
686
- let targetConversationType: AiAssistanceModel.AiHistoryStorage.ConversationType|undefined = undefined;
659
+ let targetConversationType: AiAssistanceModel.AiHistoryStorage.ConversationType|undefined;
687
660
  if (isElementsPanelVisible && hostConfig.devToolsFreestyler?.enabled) {
688
661
  targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING;
689
662
  } else if (isNetworkPanelVisible && hostConfig.devToolsAiAssistanceNetworkAgent?.enabled) {
@@ -703,7 +676,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
703
676
  // If there already is an agent and if it is not empty,
704
677
  // we don't automatically change the agent. In addition to this,
705
678
  // we don't change the current agent when there is a message in flight.
706
- if ((this.#conversationAgent && this.#conversation && !this.#conversation.isEmpty) || this.#isLoading) {
679
+ if ((this.#conversation && !this.#conversation.isEmpty) || this.#isLoading) {
707
680
  return;
708
681
  }
709
682
  const targetConversationType = this.#getDefaultConversationType();
@@ -712,59 +685,34 @@ export class AiAssistancePanel extends UI.Panel.Panel {
712
685
  // So we can just reuse it
713
686
  return;
714
687
  }
715
- const agent = targetConversationType ?
716
- this.#conversationHandler.createAgent(targetConversationType, this.#changeManager) :
688
+ const conversation = targetConversationType ?
689
+ new AiAssistanceModel.AiConversation.AiConversation(
690
+ targetConversationType, [], undefined, false, this.#aidaClient, this.#changeManager) :
717
691
  undefined;
718
- this.#updateConversationState({agent});
692
+ this.#updateConversationState(conversation);
719
693
  }
720
694
 
721
- #updateConversationState(opts?: {
722
- agent?: AiAssistanceModel.AiAgent.AiAgent<unknown>,
723
- conversation?: AiAssistanceModel.AiConversation.AiConversation,
724
- }): void {
725
- if (this.#conversationAgent !== opts?.agent) {
695
+ #updateConversationState(
696
+ conversation?: AiAssistanceModel.AiConversation.AiConversation,
697
+ ): void {
698
+ if (this.#conversation !== conversation) {
726
699
  // Cancel any previous conversation
727
700
  this.#cancel();
728
701
  this.#messages = [];
729
702
  this.#isLoading = false;
730
703
  this.#conversation?.archiveConversation();
731
- this.#conversationAgent = opts?.agent;
732
-
733
- // If we get a new agent we need to
734
- // create a new conversation along side it
735
- if (opts?.agent) {
736
- this.#conversation = new AiAssistanceModel.AiConversation.AiConversation(
737
- agentToConversationType(opts.agent),
738
- [],
739
- opts.agent.id,
740
- false,
741
- );
742
- }
743
- }
744
704
 
745
- if (!opts?.agent) {
746
- this.#conversation = undefined;
747
- // We need to run doConversation separately
748
- this.#messages = [];
749
- // If a no new agent is provided
750
- // but conversation is
751
- // update with history conversation
752
- if (opts?.conversation) {
753
- this.#conversation = opts.conversation;
705
+ if (!conversation) {
706
+ const conversationType = this.#getDefaultConversationType();
707
+ if (conversationType) {
708
+ conversation = new AiAssistanceModel.AiConversation.AiConversation(
709
+ conversationType, [], undefined, false, this.#aidaClient, this.#changeManager);
710
+ }
754
711
  }
755
- }
756
712
 
757
- if (!this.#conversationAgent && !this.#conversation) {
758
- const conversationType = this.#getDefaultConversationType();
759
- if (conversationType) {
760
- const agent = this.#conversationHandler.createAgent(conversationType, this.#changeManager);
761
- this.#updateConversationState({agent});
762
- return;
763
- }
713
+ this.#conversation = conversation;
764
714
  }
765
715
 
766
- this.#onContextSelectionChanged();
767
-
768
716
  this.requestUpdate();
769
717
  }
770
718
 
@@ -780,7 +728,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
780
728
  this.#selectedPerformanceTrace =
781
729
  createPerformanceTraceContext(UI.Context.Context.instance().flavor(AiAssistanceModel.AIContext.AgentFocus));
782
730
  this.#selectedFile = createFileContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UISourceCode));
783
- this.#updateConversationState({agent: this.#conversationAgent});
731
+ this.#updateConversationState(this.#conversation);
784
732
 
785
733
  this.#aiAssistanceEnabledSetting?.addChangeListener(this.requestUpdate, this);
786
734
  Host.AidaClient.HostConfigTracker.instance().addEventListener(
@@ -879,7 +827,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
879
827
  }
880
828
 
881
829
  this.#selectedElement = createNodeContext(selectedElementFilter(ev.data));
882
- this.#updateConversationState({agent: this.#conversationAgent});
830
+ this.#updateConversationState(this.#conversation);
883
831
  };
884
832
 
885
833
  #handleDOMNodeAttrChange =
@@ -903,7 +851,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
903
851
  } else {
904
852
  this.#selectedRequest = null;
905
853
  }
906
- this.#updateConversationState({agent: this.#conversationAgent});
854
+ this.#updateConversationState(this.#conversation);
907
855
  };
908
856
 
909
857
  #handlePerformanceTraceFlavorChange =
@@ -915,20 +863,18 @@ export class AiAssistancePanel extends UI.Panel.Panel {
915
863
  this.#selectedPerformanceTrace =
916
864
  Boolean(ev.data) ? new AiAssistanceModel.PerformanceAgent.PerformanceTraceContext(ev.data) : null;
917
865
 
918
- this.#updateConversationState({agent: this.#conversationAgent});
866
+ this.#updateConversationState(this.#conversation);
919
867
  };
920
868
 
921
869
  #handleUISourceCodeFlavorChange =
922
870
  (ev: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void => {
923
871
  const newFile = ev.data;
924
- if (!newFile) {
925
- return;
926
- }
927
- if (this.#selectedFile?.getItem() === newFile) {
872
+
873
+ if (!newFile || this.#selectedFile?.getItem() === newFile) {
928
874
  return;
929
875
  }
930
876
  this.#selectedFile = new AiAssistanceModel.FileAgent.FileContext(ev.data);
931
- this.#updateConversationState({agent: this.#conversationAgent});
877
+ this.#updateConversationState(this.#conversation);
932
878
  };
933
879
 
934
880
  #onPrimaryPageChanged(): void {
@@ -941,11 +887,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
941
887
  }
942
888
 
943
889
  #getChangeSummary(): string|undefined {
944
- if (!isAiAssistancePatchingEnabled() || !this.#conversationAgent || this.#conversation?.isReadOnly) {
890
+ if (!isAiAssistancePatchingEnabled() || !this.#conversation || this.#conversation?.isReadOnly) {
945
891
  return;
946
892
  }
947
893
 
948
- return this.#changeManager.formatChangesForPatching(this.#conversationAgent.id, /* includeSourceLocation= */ true);
894
+ return this.#changeManager.formatChangesForPatching(this.#conversation.id, /* includeSourceLocation= */ true);
949
895
  }
950
896
 
951
897
  #getToolbarInput(): ToolbarViewInput {
@@ -1185,12 +1131,12 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1185
1131
  return;
1186
1132
  }
1187
1133
 
1188
- let agent = this.#conversationAgent;
1189
- if (!this.#conversation || !this.#conversationAgent || this.#conversation.type !== targetConversationType ||
1190
- this.#conversation?.isEmpty) {
1191
- agent = this.#conversationHandler.createAgent(targetConversationType, this.#changeManager);
1134
+ let conversation = this.#conversation;
1135
+ if (!this.#conversation || this.#conversation.type !== targetConversationType || this.#conversation.isEmpty) {
1136
+ conversation = new AiAssistanceModel.AiConversation.AiConversation(
1137
+ targetConversationType, [], undefined, false, this.#aidaClient, this.#changeManager);
1192
1138
  }
1193
- this.#updateConversationState({agent});
1139
+ this.#updateConversationState(conversation);
1194
1140
  const predefinedPrompt = opts?.['prompt'];
1195
1141
  if (predefinedPrompt && typeof predefinedPrompt === 'string') {
1196
1142
  if (!this.#canExecuteQuery()) {
@@ -1214,17 +1160,13 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1214
1160
  serializedConversation =>
1215
1161
  AiAssistanceModel.AiConversation.AiConversation.fromSerializedConversation(serializedConversation));
1216
1162
  for (const conversation of historicalConversations.reverse()) {
1217
- if (conversation.isEmpty) {
1218
- continue;
1219
- }
1220
- const title = conversation.title;
1221
- if (!title) {
1163
+ if (conversation.isEmpty || !conversation.title) {
1222
1164
  continue;
1223
1165
  }
1224
1166
 
1225
- contextMenu.defaultSection().appendCheckboxItem(title, () => {
1167
+ contextMenu.defaultSection().appendCheckboxItem(conversation.title, () => {
1226
1168
  void this.#openHistoricConversation(conversation);
1227
- }, {checked: (this.#conversation === conversation), jslogContext: 'freestyler.history-item'});
1169
+ }, {checked: (this.#conversation?.id === conversation.id), jslogContext: 'freestyler.history-item'});
1228
1170
  }
1229
1171
 
1230
1172
  const historyEmpty = contextMenu.defaultSection().items.length === 0;
@@ -1282,11 +1224,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1282
1224
  }
1283
1225
 
1284
1226
  async #openHistoricConversation(conversation: AiAssistanceModel.AiConversation.AiConversation): Promise<void> {
1285
- if (this.#conversation === conversation) {
1227
+ if (this.#conversation?.id === conversation.id) {
1286
1228
  return;
1287
1229
  }
1288
1230
 
1289
- this.#updateConversationState({conversation});
1231
+ this.#updateConversationState(conversation);
1290
1232
  await this.#doConversation(conversation.history);
1291
1233
  }
1292
1234
 
@@ -1355,10 +1297,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1355
1297
  this.#imageInput = {isLoading: true};
1356
1298
  this.requestUpdate();
1357
1299
  }, SHOW_LOADING_STATE_TIMEOUT);
1358
- const reader = new FileReader();
1359
- let dataUrl: string|undefined;
1360
1300
  try {
1361
- dataUrl = await new Promise<string>((resolve, reject) => {
1301
+ const reader = new FileReader();
1302
+ const dataUrl = await new Promise<string>((resolve, reject) => {
1362
1303
  reader.onload = () => {
1363
1304
  if (typeof reader.result === 'string') {
1364
1305
  resolve(reader.result);
@@ -1368,31 +1309,22 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1368
1309
  };
1369
1310
  reader.readAsDataURL(file);
1370
1311
  });
1312
+ const commaIndex = dataUrl.indexOf(',');
1313
+ const bytes = dataUrl.substring(commaIndex + 1);
1314
+ this.#imageInput = {
1315
+ isLoading: false,
1316
+ data: bytes,
1317
+ mimeType: file.type,
1318
+ inputType: AiAssistanceModel.AiAgent.MultimodalInputType.UPLOADED_IMAGE
1319
+ };
1371
1320
  } catch {
1372
- clearTimeout(showLoadingTimeout);
1373
1321
  this.#imageInput = undefined;
1374
- this.requestUpdate();
1375
- void this.updateComplete.then(() => {
1376
- this.#viewOutput.chatView?.focusTextInput();
1377
- });
1378
1322
  Snackbars.Snackbar.Snackbar.show({
1379
1323
  message: lockedString(UIStringsNotTranslate.uploadImageFailureMessage),
1380
1324
  });
1381
- return;
1382
1325
  }
1383
1326
 
1384
1327
  clearTimeout(showLoadingTimeout);
1385
- if (!dataUrl) {
1386
- return;
1387
- }
1388
- const commaIndex = dataUrl.indexOf(',');
1389
- const bytes = dataUrl.substring(commaIndex + 1);
1390
- this.#imageInput = {
1391
- isLoading: false,
1392
- data: bytes,
1393
- mimeType: file.type,
1394
- inputType: AiAssistanceModel.AiAgent.MultimodalInputType.UPLOADED_IMAGE
1395
- };
1396
1328
  this.requestUpdate();
1397
1329
  void this.updateComplete.then(() => {
1398
1330
  this.#viewOutput.chatView?.focusTextInput();
@@ -1404,21 +1336,18 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1404
1336
  this.#runAbortController = new AbortController();
1405
1337
  }
1406
1338
 
1407
- #onContextSelectionChanged(): void {
1408
- if (!this.#conversationAgent) {
1409
- this.#blockedByCrossOrigin = false;
1410
- return;
1339
+ // Indicates whether the new conversation context is blocked due to cross-origin restrictions.
1340
+ // This happens when the conversation's context has a different
1341
+ // origin than the selected context.
1342
+ get #blockedByCrossOrigin(): boolean {
1343
+ if (!this.#conversation) {
1344
+ return false;
1411
1345
  }
1412
1346
  this.#selectedContext = this.#getConversationContext(this.#conversation);
1413
1347
  if (!this.#selectedContext) {
1414
- this.#blockedByCrossOrigin = false;
1415
-
1416
- // Clear out any text the user has entered into the input but never
1417
- // submitted now they have no active context
1418
- this.#viewOutput.chatView?.clearTextInput();
1419
- return;
1348
+ return false;
1420
1349
  }
1421
- this.#blockedByCrossOrigin = !this.#selectedContext.isOriginAllowed(this.#conversationAgent.origin);
1350
+ return !this.#selectedContext.isOriginAllowed(this.#conversation.origin);
1422
1351
  }
1423
1352
 
1424
1353
  #getConversationContext(conversation?: AiAssistanceModel.AiConversation.AiConversation):
@@ -1445,9 +1374,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1445
1374
  }
1446
1375
 
1447
1376
  async #startConversation(
1448
- text: string, imageInput?: Host.AidaClient.Part,
1449
- multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType): Promise<void> {
1450
- if (!this.#conversationAgent) {
1377
+ text: string,
1378
+ imageInput?: Host.AidaClient.Part,
1379
+ multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType,
1380
+ ): Promise<void> {
1381
+ if (!this.#conversation) {
1451
1382
  return;
1452
1383
  }
1453
1384
  // Cancel any previous in-flight conversation.
@@ -1455,34 +1386,31 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1455
1386
  const signal = this.#runAbortController.signal;
1456
1387
  const context = this.#getConversationContext(this.#conversation);
1457
1388
  // If a different context is provided, it must be from the same origin.
1458
- if (context && !context.isOriginAllowed(this.#conversationAgent.origin)) {
1389
+ if (context && !context.isOriginAllowed(this.#conversation.origin)) {
1459
1390
  // This error should not be reached. If it happens, some
1460
1391
  // invariants do not hold anymore.
1461
1392
  throw new Error('cross-origin context data should not be included');
1462
1393
  }
1463
- if (this.#conversation?.isEmpty) {
1394
+ if (this.#conversation.isEmpty) {
1464
1395
  Badges.UserBadges.instance().recordAction(Badges.BadgeAction.STARTED_AI_CONVERSATION);
1465
1396
  }
1466
- const image = isAiAssistanceMultimodalInputEnabled() ? imageInput : undefined;
1467
- const imageId = image ? crypto.randomUUID() : undefined;
1468
- const multimodalInput = image && imageId && multimodalInputType ? {
1469
- input: image,
1470
- id: imageId,
1397
+ const multimodalInput = isAiAssistanceMultimodalInputEnabled() && imageInput && multimodalInputType ? {
1398
+ input: imageInput,
1399
+ id: crypto.randomUUID(),
1471
1400
  type: multimodalInputType,
1472
1401
  } :
1473
- undefined;
1474
- if (this.#conversation) {
1475
- void VisualLogging.logFunctionCall(`start-conversation-${this.#conversation.type}`, 'ui');
1476
- }
1402
+ undefined;
1477
1403
 
1478
- const generator = this.#conversationAgent.run(
1479
- text, {
1480
- signal,
1481
- selected: context,
1482
- },
1483
- multimodalInput);
1484
- const generatorWithHistory = this.#conversationHandler.handleConversationWithHistory(generator, this.#conversation);
1485
- await this.#doConversation(generatorWithHistory);
1404
+ void VisualLogging.logFunctionCall(`start-conversation-${this.#conversation.type}`, 'ui');
1405
+
1406
+ await this.#doConversation(
1407
+ this.#conversation.run(
1408
+ text, {
1409
+ signal,
1410
+ selected: context,
1411
+ },
1412
+ multimodalInput),
1413
+ );
1486
1414
  }
1487
1415
 
1488
1416
  async #doConversation(
@@ -1655,8 +1583,7 @@ export function getResponseMarkdown(message: ModelChatMessage): string {
1655
1583
  contentParts.push(`### ${step.title}`);
1656
1584
  }
1657
1585
  if (step.contextDetails) {
1658
- contentParts.push(
1659
- AiAssistanceModel.AiConversation.AiConversation.generateContextDetailsMarkdown(step.contextDetails));
1586
+ contentParts.push(AiAssistanceModel.AiConversation.generateContextDetailsMarkdown(step.contextDetails));
1660
1587
  }
1661
1588
  if (step.thought) {
1662
1589
  contentParts.push(step.thought);
@@ -303,14 +303,6 @@ export class ChatView extends HTMLElement {
303
303
  this.#messagesContainerResizeObserver.disconnect();
304
304
  }
305
305
 
306
- clearTextInput(): void {
307
- const textArea = this.#shadow.querySelector('.chat-input') as HTMLTextAreaElement;
308
- if (!textArea) {
309
- return;
310
- }
311
- textArea.value = '';
312
- }
313
-
314
306
  focusTextInput(): void {
315
307
  const textArea = this.#shadow.querySelector('.chat-input') as HTMLTextAreaElement;
316
308
  if (!textArea) {
@@ -954,6 +946,9 @@ function renderSelection({
954
946
  onInspectElementClick: () => void,
955
947
  conversationType: AiAssistanceModel.AiHistoryStorage.ConversationType,
956
948
  }): Lit.LitTemplate {
949
+ if (!selectedContext) {
950
+ return Lit.nothing;
951
+ }
957
952
  // TODO: currently the picker behavior is SDKNode specific.
958
953
  const hasPickerBehavior = conversationType === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING;
959
954
 
@@ -964,10 +959,6 @@ function renderSelection({
964
959
  disabled: isTextInputDisabled,
965
960
  });
966
961
 
967
- if (!selectedContext && !hasPickerBehavior) {
968
- return Lit.nothing;
969
- }
970
-
971
962
  const handleKeyDown = (ev: KeyboardEvent): void => {
972
963
  if (ev.key === 'Enter' || ev.key === ' ') {
973
964
  void onContextClick();
@@ -1307,8 +1298,10 @@ function renderRelevantDataDisclaimer({isLoading, blockedByCrossOrigin, tooltipI
1307
1298
  tooltipId: string,
1308
1299
  disclaimerText: string,
1309
1300
  }): Lit.LitTemplate {
1310
- const classes =
1311
- Lit.Directives.classMap({'chat-input-disclaimer': true, 'hide-divider': !isLoading && blockedByCrossOrigin});
1301
+ const classes = Lit.Directives.classMap({
1302
+ 'chat-input-disclaimer': true,
1303
+ 'hide-divider': !isLoading && blockedByCrossOrigin,
1304
+ });
1312
1305
  // clang-format off
1313
1306
  return html`
1314
1307
  <p class=${classes}>
@@ -1323,7 +1316,7 @@ function renderRelevantDataDisclaimer({isLoading, blockedByCrossOrigin, tooltipI
1323
1316
  void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
1324
1317
  }}
1325
1318
  >${lockedString('Relevant data')}</button>&nbsp;${lockedString('is sent to Google')}
1326
- ${renderDisclamerTooltip(tooltipId, disclaimerText)}
1319
+ ${renderDisclaimerTooltip(tooltipId, disclaimerText)}
1327
1320
  </p>
1328
1321
  `;
1329
1322
  // clang-format on
@@ -1376,50 +1369,80 @@ function renderChatInput({
1376
1369
  onRemoveImageInput?: () => void,
1377
1370
  onImageUpload?: (ev: Event) => void,
1378
1371
  }): Lit.LitTemplate {
1379
- const shouldShowMultiLine = selectedContext;
1380
1372
  const chatInputContainerCls = Lit.Directives.classMap({
1381
1373
  'chat-input-container': true,
1382
- 'single-line-layout': !shouldShowMultiLine,
1374
+ 'single-line-layout': !selectedContext,
1383
1375
  disabled: isTextInputDisabled,
1384
1376
  });
1385
1377
 
1386
1378
  // clang-format off
1387
- return html`
1388
- <form class="input-form" @submit=${onSubmit}>
1379
+ return html` <form class="input-form" @submit=${onSubmit}>
1389
1380
  <div class=${chatInputContainerCls}>
1390
- ${renderImageInput(
1391
- {multimodalInputEnabled, imageInput, isTextInputDisabled, onRemoveImageInput}
1392
- )}
1393
- <textarea class="chat-input"
1381
+ ${renderImageInput({
1382
+ multimodalInputEnabled,
1383
+ imageInput,
1384
+ isTextInputDisabled,
1385
+ onRemoveImageInput,
1386
+ })}
1387
+ <textarea
1388
+ class="chat-input"
1394
1389
  .disabled=${isTextInputDisabled}
1395
1390
  wrap="hard"
1396
1391
  maxlength="10000"
1397
1392
  @keydown=${onTextAreaKeyDown}
1398
- @input=${(event: KeyboardEvent) => onTextInputChange((event.target as HTMLInputElement).value)}
1393
+ @input=${(event: KeyboardEvent) =>
1394
+ onTextInputChange((event.target as HTMLInputElement).value)}
1399
1395
  placeholder=${inputPlaceholder}
1400
- jslog=${VisualLogging.textField('query').track({change: true, keydown: 'Enter'})}
1396
+ jslog=${VisualLogging.textField('query').track({
1397
+ change: true,
1398
+ keydown: 'Enter',
1399
+ })}
1401
1400
  aria-description=${i18nString(UIStrings.inputTextAriaDescription)}
1401
+ ${ref(el => {
1402
+ // If the elements is disabled reset the text to show
1403
+ // the place holder
1404
+ if (el && isTextInputDisabled) {
1405
+ (el as HTMLInputElement).value = '';
1406
+ }
1407
+ })}
1402
1408
  ></textarea>
1403
1409
  <div class="chat-input-actions">
1404
1410
  <div class="chat-input-actions-left">
1405
- ${shouldShowMultiLine ? renderSelection({
1411
+ ${renderSelection({
1406
1412
  selectedContext,
1407
1413
  inspectElementToggled,
1408
1414
  conversationType,
1409
1415
  isTextInputDisabled,
1410
1416
  onContextClick,
1411
1417
  onInspectElementClick,
1412
- }) : Lit.nothing}
1418
+ })}
1413
1419
  </div>
1414
1420
  <div class="chat-input-actions-right">
1415
1421
  <div class="chat-input-disclaimer-container">
1416
- ${renderRelevantDataDisclaimer({ isLoading, blockedByCrossOrigin, tooltipId: RELEVANT_DATA_LINK_CHAT_ID, disclaimerText})}
1422
+ ${renderRelevantDataDisclaimer({
1423
+ isLoading,
1424
+ blockedByCrossOrigin,
1425
+ tooltipId: RELEVANT_DATA_LINK_CHAT_ID,
1426
+ disclaimerText,
1427
+ })}
1417
1428
  </div>
1418
1429
  ${renderMultimodalInputButtons({
1419
- multimodalInputEnabled, blockedByCrossOrigin, isTextInputDisabled, imageInput, uploadImageInputEnabled, onTakeScreenshot, onImageUpload
1430
+ multimodalInputEnabled,
1431
+ blockedByCrossOrigin,
1432
+ isTextInputDisabled,
1433
+ imageInput,
1434
+ uploadImageInputEnabled,
1435
+ onTakeScreenshot,
1436
+ onImageUpload,
1420
1437
  })}
1421
1438
  ${renderChatInputButtons({
1422
- isLoading, blockedByCrossOrigin, isTextInputDisabled, isTextInputEmpty, imageInput, onCancel, onNewConversation
1439
+ isLoading,
1440
+ blockedByCrossOrigin,
1441
+ isTextInputDisabled,
1442
+ isTextInputEmpty,
1443
+ imageInput,
1444
+ onCancel,
1445
+ onNewConversation,
1423
1446
  })}
1424
1447
  </div>
1425
1448
  </div>
@@ -1479,7 +1502,7 @@ function renderMainContents({
1479
1502
  return renderEmptyState({isTextInputDisabled, suggestions, onSuggestionClick});
1480
1503
  }
1481
1504
 
1482
- function renderDisclamerTooltip(id: string, disclaimerText: string): Lit.TemplateResult {
1505
+ function renderDisclaimerTooltip(id: string, disclaimerText: string): Lit.TemplateResult {
1483
1506
  // clang-format off
1484
1507
  return html`
1485
1508
  <devtools-tooltip
@@ -196,7 +196,7 @@ export class ExtensionStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
196
196
 
197
197
  #extensionIdForContext(context: SDK.RuntimeModel.ExecutionContext): string|undefined {
198
198
  const url = Common.ParsedURL.ParsedURL.fromString(context.origin);
199
- return url && url.scheme === 'chrome-extension' ? url.host : undefined;
199
+ return url?.scheme === 'chrome-extension' ? url.host : undefined;
200
200
  }
201
201
 
202
202
  #executionContextDestroyed(context: SDK.RuntimeModel.ExecutionContext): void {