chrome-devtools-frontend 1.0.1717709 → 1.0.1721762
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.
- package/.agents/rules/models-and-core/core-ai-agent-context-and-prompt-discipline.md +29 -0
- package/.agents/rules/models-and-core/core-cdp-and-extension-error-handling.md +34 -0
- package/.agents/rules/models-and-core/core-gn-build-and-module-layering.md +23 -0
- package/.agents/rules/models-and-core/core-runtime-neutrality-and-platform-utils.md +28 -0
- package/.agents/rules/models-and-core/core-sdk-model-and-target-lifecycle.md +35 -0
- package/.agents/rules/models-and-core/core-security-origin-and-capability-guards.md +33 -0
- package/.agents/rules/models-and-core/core-settings-and-storage-migration.md +31 -0
- package/.agents/rules/models-and-core/core-sourcemap-and-workspace-mapping.md +28 -0
- package/.agents/rules/models-and-core/core-trace-engine-handler-invariants.md +32 -0
- package/.agents/rules/models-and-core/core-trace-insight-models-and-timing-types.md +28 -0
- package/.agents/rules/tests/test-cleanup-mutated-globals-and-widgets.md +40 -0
- package/.agents/rules/tests/test-deterministic-async-synchronization.md +30 -0
- package/.agents/rules/tests/test-modular-hooks-and-test-universe.md +38 -0
- package/.agents/rules/tests/test-public-api-and-encapsulation.md +30 -0
- package/.agents/rules/tests/test-shared-fixture-and-helper-reuse.md +29 -0
- package/.agents/rules/tests/test-single-responsibility-and-conciseness.md +37 -0
- package/.agents/rules/tests/test-strict-assertions-and-literal-expectations.md +31 -0
- package/.agents/rules/tests/test-type-safe-mocks-and-events.md +30 -0
- package/.agents/rules/tests/test-view-and-presenter-isolation.md +32 -0
- package/.agents/rules/ui-and-widgets/ui-accessibility-and-semantic-html.md +32 -0
- package/.agents/rules/ui-and-widgets/ui-await-update-complete-post-render.md +30 -0
- package/.agents/rules/ui-and-widgets/ui-css-scoping-and-flex-layout.md +27 -0
- package/.agents/rules/ui-and-widgets/ui-declarative-child-widget-composition.md +29 -0
- package/.agents/rules/ui-and-widgets/ui-lit-declarative-templates-and-directives.md +33 -0
- package/.agents/rules/ui-and-widgets/ui-localization-and-uistrings-hygiene.md +36 -0
- package/.agents/rules/ui-and-widgets/ui-modern-component-and-encapsulation-standards.md +32 -0
- package/.agents/rules/ui-and-widgets/ui-panel-and-meta-registration.md +35 -0
- package/.agents/rules/ui-and-widgets/ui-performance-and-flamechart-rendering.md +34 -0
- package/.agents/rules/ui-and-widgets/ui-pure-view-and-presenter-separation.md +31 -0
- package/.agents/rules/ui-and-widgets/ui-reactive-widget-update-lifecycle.md +34 -0
- package/.agents/rules/ui-and-widgets/ui-security-and-output-sanitization.md +28 -0
- package/.agents/rules/ui-and-widgets/ui-type-safety-and-exhaustiveness.md +37 -0
- package/.agents/rules/ui-and-widgets/ui-view-output-and-callback-contracts.md +35 -0
- package/.agents/rules/ui-and-widgets/ui-visual-logging-instrumentation.md +29 -0
- package/.agents/rules/ui-and-widgets/ui-weak-dom-references-and-observer-cleanup.md +29 -0
- package/.agents/rules/ui-and-widgets/ui-widget-dom-and-listener-lifecycle.md +38 -0
- package/.agents/skills/code-review/SKILL.md +3 -0
- package/.agents/skills/devtools-testing-guidance/SKILL.md +1 -0
- package/.agents/skills/review-models-core/SKILL.md +73 -0
- package/.agents/skills/review-tests/SKILL.md +67 -0
- package/.agents/skills/review-ui-widgets/SKILL.md +115 -0
- package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +19 -3
- package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +2 -1
- package/.agents/skills/ui-widgets/SKILL.md +3 -1
- package/AUTHORS +3 -0
- package/DIR_METADATA +51 -1
- package/eslint.config.mjs +63 -21
- package/front_end/core/platform/api/HostRuntime.ts +1 -0
- package/front_end/core/platform/browser/HostRuntime.ts +10 -0
- package/front_end/core/platform/node/HostRuntime.ts +1 -0
- package/front_end/core/sdk/CSSMatchedStyles.ts +60 -20
- package/front_end/core/sdk/CSSProperty.ts +2 -2
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +28 -9
- package/front_end/core/sdk/NetworkManager.ts +9 -3
- package/front_end/core/sdk/OverlayModel.ts +2 -8
- package/front_end/core/sdk/PrivateVerificationTokensModel.ts +79 -0
- package/front_end/core/sdk/SecurityOrigin.ts +1 -1
- package/front_end/core/sdk/SourceMapCache.ts +20 -15
- package/front_end/core/sdk/SourceMapManager.ts +28 -9
- package/front_end/core/sdk/TargetManager.ts +7 -4
- package/front_end/core/sdk/WebAuthnModel.ts +11 -2
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/entrypoints/inspector_main/InspectorMain.ts +0 -2
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +10 -0
- package/front_end/entrypoints/main/GlobalAiButton.ts +1 -1
- package/front_end/entrypoints/main/MainImpl.ts +5 -2
- package/front_end/foundation/Universe.ts +1 -1
- package/front_end/generated/Deprecation.ts +4 -0
- package/front_end/generated/InspectorBackendCommands.ts +3 -3
- package/front_end/generated/SupportedCSSProperties.ts +89 -17
- package/front_end/generated/protocol-mapping.d.ts +1 -0
- package/front_end/generated/protocol-proxy-api.d.ts +1 -0
- package/front_end/generated/protocol.ts +5 -3
- package/front_end/models/{ai_assistance → ai-utils}/AiHistoryStorage.ts +6 -5
- package/front_end/models/{ai_assistance → ai-utils}/AiUtils.ts +9 -0
- package/front_end/models/{ai_assistance → ai-utils}/BuiltInAi.ts +1 -1
- package/front_end/models/ai-utils/ai-utils.ts +17 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +3 -1
- package/front_end/models/ai_assistance/AiConversation.ts +34 -22
- package/front_end/models/ai_assistance/AlwaysAllowedTools.ts +107 -0
- package/front_end/models/ai_assistance/ConversationSummary.ts +2 -1
- package/front_end/models/ai_assistance/PerformanceAnnotations.ts +3 -1
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +3 -1
- package/front_end/models/ai_assistance/agents/AiAgent.ts +15 -7
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +3 -1
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +3 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -1
- package/front_end/models/ai_assistance/ai_assistance.ts +9 -10
- package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +27 -6
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +3 -3
- package/front_end/models/ai_assistance/skills/sources.md +3 -1
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +1 -0
- package/front_end/models/ai_assistance/tools/GetCookieValues.ts +1 -0
- package/front_end/models/ai_assistance/tools/GetInsightDetails.ts +3 -1
- package/front_end/models/ai_assistance/tools/GetSourceContent.ts +46 -4
- package/front_end/models/ai_assistance/tools/GetStorageValues.ts +1 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +6 -0
- package/front_end/models/breakpoints/BreakpointManager.ts +0 -4
- package/front_end/models/change_tracker/ChangeTracker.ts +2 -0
- package/front_end/models/comment_manager/CommentManager.ts +12 -0
- package/front_end/models/comment_manager/CommentThread.ts +21 -1
- package/front_end/models/elements/ChangeTrackingUtils.ts +37 -0
- package/front_end/models/elements/DOMChanges.ts +24 -36
- package/front_end/models/elements/StyleChanges.ts +97 -0
- package/front_end/models/elements/elements.ts +4 -0
- package/front_end/models/emulation/DeviceModeModel.ts +19 -0
- package/front_end/models/javascript_metadata/NativeFunctions.ts +11 -1
- package/front_end/models/trace/EventsSerializer.ts +35 -2
- package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +17 -21
- package/front_end/models/trace/helpers/SyntheticEvents.ts +4 -2
- package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +12 -8
- package/front_end/models/trace/types/File.ts +20 -3
- package/front_end/models/trace/types/TraceEvents.ts +8 -3
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +14 -0
- package/front_end/panels/ai_assistance/README.md +1 -1
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +1 -1
- package/front_end/panels/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +5 -43
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +52 -147
- package/front_end/panels/ai_assistance/components/ChatView.ts +28 -3
- package/front_end/panels/ai_assistance/components/PermissionPrompt.ts +151 -0
- package/front_end/panels/ai_assistance/components/RelevantDataDisclaimer.ts +73 -0
- package/front_end/panels/ai_assistance/components/chatInput.css +0 -59
- package/front_end/panels/ai_assistance/components/chatMessage.css +0 -47
- package/front_end/panels/ai_assistance/components/chatView.css +5 -30
- package/front_end/panels/ai_assistance/components/permissionPrompt.css +55 -0
- package/front_end/panels/ai_assistance/components/relevantDataDisclaimer.css +35 -0
- package/front_end/panels/application/ApplicationPanelSidebar.ts +3 -7
- package/front_end/panels/application/BackgroundServiceView.ts +8 -8
- package/front_end/panels/application/IndexedDBViews.ts +102 -73
- package/front_end/panels/application/OpenedWindowDetailsView.ts +167 -130
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +288 -346
- package/front_end/panels/application/StorageBucketsTreeElement.ts +22 -27
- package/front_end/panels/application/StorageItemsToolbar.ts +2 -2
- package/front_end/panels/application/components/StorageMetadataView.ts +207 -160
- package/front_end/panels/application/openedWindowDetailsView.css +7 -30
- package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +1 -1
- package/front_end/panels/changes/changesView.css +0 -6
- package/front_end/panels/console/ConsoleInsightTeaser.ts +5 -1
- package/front_end/panels/console/ConsolePinPane.ts +1 -1
- package/front_end/panels/console/ConsoleView.ts +1 -0
- package/front_end/panels/elements/CSSValueTraceView.ts +5 -5
- package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +14 -6
- package/front_end/panels/elements/ComputedStyleWidget.ts +14 -5
- package/front_end/panels/elements/DOMTreeElementWidget.ts +2 -2
- package/front_end/panels/elements/DOMTreeWidget.ts +7 -3
- package/front_end/panels/elements/EventListenersWidget.ts +1 -1
- package/front_end/panels/elements/LayersWidget.ts +1 -1
- package/front_end/panels/elements/PropertyRenderer.ts +91 -16
- package/front_end/panels/elements/StandaloneStylesContainer.ts +33 -6
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -0
- package/front_end/panels/elements/StylePropertyTreeElement.ts +211 -121
- package/front_end/panels/elements/StylesContainer.ts +2 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +34 -16
- package/front_end/panels/elements/components/QueryContainer.ts +1 -1
- package/front_end/panels/elements/elementStatePaneWidget.css +1 -1
- package/front_end/panels/elements/stylePropertiesTreeOutline.css +1 -1
- package/front_end/panels/elements/stylesSidebarPane.css +4 -0
- package/front_end/panels/emulation/DeviceModeToolbar.ts +57 -25
- package/front_end/panels/emulation/DeviceModeView.ts +27 -1
- package/front_end/panels/emulation/InspectedPagePlaceholder.ts +6 -0
- package/front_end/panels/emulation/MediaQueryInspector.ts +14 -4
- package/front_end/panels/explain/components/ConsoleInsight.ts +2 -3
- package/front_end/panels/explain/explain-meta.ts +1 -1
- package/front_end/panels/issues/AffectedMetadataAllowedSitesView.ts +67 -34
- package/front_end/panels/issues/issues.ts +2 -0
- package/front_end/panels/layer_viewer/LayerTreeOutline.ts +7 -3
- package/front_end/panels/lighthouse/LighthouseController.ts +1 -1
- package/front_end/panels/media/PlayerMessagesView.ts +1 -1
- package/front_end/panels/mobile_throttling/CPUThrottlingSelector.ts +1 -1
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +45 -15
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +3 -3
- package/front_end/panels/network/BinaryResourceView.ts +54 -50
- package/front_end/panels/network/RequestHeadersView.ts +6 -2
- package/front_end/panels/network/RequestPreviewView.ts +28 -5
- package/front_end/panels/network/ResourceWebSocketFrameView.ts +1 -0
- package/front_end/panels/network/components/EditableSpan.ts +11 -30
- package/front_end/panels/network/components/HeaderSectionRow.ts +2 -2
- package/front_end/panels/performance_monitor/PerformanceMonitor.ts +10 -6
- package/front_end/panels/profiler/HeapDetachedElementsView.ts +112 -22
- package/front_end/panels/profiler/HeapProfileView.ts +3 -3
- package/front_end/panels/profiler/HeapSnapshotView.ts +12 -2
- package/front_end/panels/profiler/HeapTimelineOverview.ts +16 -2
- package/front_end/panels/profiler/profiler.ts +0 -2
- package/front_end/panels/protocol_monitor/JSONEditor.ts +1 -1
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +1 -1
- package/front_end/panels/recorder/CreateRecordingView.ts +1 -1
- package/front_end/panels/recorder/RecordingView.ts +3 -3
- package/front_end/panels/recorder/ReplaySection.ts +1 -1
- package/front_end/panels/screencast/ScreencastApp.ts +83 -57
- package/front_end/panels/screencast/screencastView.css +1 -1
- package/front_end/panels/settings/AISettingsTab.ts +107 -4
- package/front_end/panels/settings/aiSettingsTab.css +53 -0
- package/front_end/panels/settings/settings-meta.ts +1 -1
- package/front_end/panels/settings/settingsScreen.css +0 -4
- package/front_end/panels/sources/BreakpointsView.ts +2 -2
- package/front_end/panels/sources/DebuggerPlugin.ts +7 -0
- package/front_end/panels/sources/NavigatorView.ts +61 -18
- package/front_end/panels/sources/SourcesNavigator.ts +22 -7
- package/front_end/panels/sources/SourcesPanel.ts +1 -0
- package/front_end/panels/timeline/README.md +12 -0
- package/front_end/panels/timeline/StatusDialog.ts +1 -1
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -3
- package/front_end/panels/timeline/TimelineCommentController.ts +346 -0
- package/front_end/panels/timeline/TimelineDetailsView.ts +24 -1
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +34 -30
- package/front_end/panels/timeline/TimelineFlameChartView.ts +22 -1
- package/front_end/panels/timeline/TimelinePanel.ts +12 -5
- package/front_end/panels/timeline/TimelineTreeView.ts +28 -6
- package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -1
- package/front_end/panels/timeline/components/fieldSettingsDialog.css +2 -2
- package/front_end/panels/timeline/components/insights/baseInsightComponent.css +1 -1
- package/front_end/panels/timeline/overlays/components/entriesLinkOverlay.css +2 -2
- package/front_end/panels/timeline/overlays/components/entryLabelOverlay.css +9 -9
- package/front_end/panels/timeline/timeline-meta.ts +2 -2
- package/front_end/panels/timeline/timeline.ts +4 -0
- package/front_end/panels/timeline/timelineFlamechartPopover.css +2 -2
- package/front_end/panels/timeline/timelinePanel.css +2 -2
- package/front_end/panels/web_audio/WebAudioView.ts +7 -4
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/rollup.config.mjs +1 -1
- package/front_end/tsconfig.json +1 -1
- package/front_end/ui/comments/CommentAnchorResolver.ts +1 -1
- package/front_end/ui/components/buttons/Button.ts +29 -18
- package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +1 -1
- package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +94 -39
- package/front_end/ui/components/dialogs/dialog.css +1 -1
- package/front_end/ui/components/menus/menuItem.css +11 -0
- package/front_end/ui/components/text_editor/AccessiblePlaceholder.ts +1 -1
- package/front_end/ui/components/text_editor/AiCodeCompletionTeaser.ts +1 -1
- package/front_end/ui/components/text_editor/config.ts +2 -1
- package/front_end/ui/components/text_editor/javascript.ts +2 -1
- package/front_end/ui/legacy/InspectorView.ts +4 -2
- package/front_end/ui/legacy/SplitWidget.ts +14 -16
- package/front_end/ui/legacy/TabbedPane.ts +9 -1
- package/front_end/ui/legacy/UIUtils.ts +60 -40
- package/front_end/ui/legacy/components/color_picker/spectrum.css +2 -2
- package/front_end/ui/legacy/components/data_grid/dataGrid.css +9 -0
- package/front_end/ui/legacy/components/inline_editor/CSSAngle.ts +0 -1
- package/front_end/ui/legacy/components/inline_editor/cssShadowEditor.css +5 -7
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/PieChart.ts +11 -0
- package/front_end/ui/legacy/components/perf_ui/chartViewport.css +4 -4
- package/front_end/ui/legacy/components/quick_open/filteredListWidget.css +6 -0
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +38 -13
- package/front_end/ui/legacy/dropTarget.css +1 -1
- package/front_end/ui/legacy/statusBar.css +7 -0
- package/front_end/ui/legacy/tabbedPane.css +0 -7
- package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
- package/inspector_overlay/main.ts +2 -15
- package/inspector_overlay/tool_persistent.ts +0 -14
- package/mcp/mcp.ts +3 -0
- package/package.json +1 -1
- package/front_end/panels/ai_assistance/components/StylingAgentMarkdownRenderer.ts +0 -178
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +0 -147
- package/front_end/panels/profiler/heapDetachedElementsDataGrid.css +0 -14
- package/front_end/ui/components/legacy_wrapper/LegacyWrapper.ts +0 -62
- package/front_end/ui/components/legacy_wrapper/legacy_wrapper.ts +0 -8
- package/inspector_overlay/tool_green_dev_anchors.css +0 -54
- package/inspector_overlay/tool_green_dev_anchors.ts +0 -164
- /package/front_end/models/{ai_assistance → ai-utils}/AiSetting.ts +0 -0
- /package/front_end/models/{ai_assistance → ai-utils}/debug.ts +0 -0
|
@@ -362,26 +362,23 @@ async function buildLayoutShiftsClusters(): Promise<void> {
|
|
|
362
362
|
navigationId = Types.Events.NO_NAVIGATION;
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
clusters.push(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
cat: '',
|
|
383
|
-
dur: Types.Timing.Micro(-1), // This `cluster.dur` is updated below.
|
|
384
|
-
}));
|
|
365
|
+
clusters.push({
|
|
366
|
+
name: 'SyntheticLayoutShiftCluster',
|
|
367
|
+
events: [],
|
|
368
|
+
clusterWindow: traceWindowFromTime(clusterStartTime),
|
|
369
|
+
clusterCumulativeScore: 0,
|
|
370
|
+
scoreWindows: {
|
|
371
|
+
good: traceWindowFromTime(clusterStartTime),
|
|
372
|
+
},
|
|
373
|
+
navigationId,
|
|
374
|
+
// Set default Event so that this event is treated accordingly for the track appender.
|
|
375
|
+
ts: event.ts,
|
|
376
|
+
pid: event.pid,
|
|
377
|
+
tid: event.tid,
|
|
378
|
+
ph: Types.Events.Phase.COMPLETE,
|
|
379
|
+
cat: '',
|
|
380
|
+
dur: Types.Timing.Micro(-1), // This `cluster.dur` is updated below.
|
|
381
|
+
});
|
|
385
382
|
|
|
386
383
|
firstShiftTime = clusterStartTime;
|
|
387
384
|
}
|
|
@@ -510,7 +507,6 @@ async function buildLayoutShiftsClusters(): Promise<void> {
|
|
|
510
507
|
// Update the cluster's worst layout shift.
|
|
511
508
|
if (worstShiftEvent) {
|
|
512
509
|
cluster.worstShiftEvent = worstShiftEvent;
|
|
513
|
-
cluster.rawSourceEvent = worstShiftEvent.rawSourceEvent;
|
|
514
510
|
}
|
|
515
511
|
|
|
516
512
|
// layout shifts are already sorted by time ascending.
|
|
@@ -8,8 +8,10 @@ let activeManager: SyntheticEventsManager|null = null;
|
|
|
8
8
|
|
|
9
9
|
export class SyntheticEventsManager {
|
|
10
10
|
/**
|
|
11
|
-
* All synthetic entries created in a trace from
|
|
12
|
-
*
|
|
11
|
+
* All synthetic entries created in a trace from
|
|
12
|
+
* corresponding trace events.
|
|
13
|
+
* (ProfileCalls and layout shift clusters are excluded
|
|
14
|
+
* because they are not based on a real trace event.)
|
|
13
15
|
*/
|
|
14
16
|
#syntheticTraces: Types.Events.SyntheticBased[] = [];
|
|
15
17
|
/**
|
|
@@ -589,16 +589,20 @@ class NetworkAnalyzer {
|
|
|
589
589
|
return exactMatch;
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
-
// Cross-origin redirects in renderer trace events have their pre-redirect URL
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return records.find(
|
|
596
|
-
request => Boolean(request.redirectDestination) && originUrl.startsWith(request.url) &&
|
|
597
|
-
UrlUtils.equalWithExcludedFragments(request.url, originUrl),
|
|
598
|
-
);
|
|
599
|
-
} catch {
|
|
592
|
+
// Cross-origin document redirects in renderer trace events have their pre-redirect URL scrubbed to the origin.
|
|
593
|
+
const origin = URL.parse(resourceUrl)?.origin;
|
|
594
|
+
if (!origin) {
|
|
600
595
|
return undefined;
|
|
601
596
|
}
|
|
597
|
+
|
|
598
|
+
return records.find(request => {
|
|
599
|
+
if (!request.redirectDestination || request.url !== `${origin}/`) {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
const finalRequest = NetworkAnalyzer.resolveRedirects(request);
|
|
603
|
+
return finalRequest.resourceType === 'Document' && !finalRequest.failed &&
|
|
604
|
+
URL.parse(finalRequest.url)?.origin !== origin;
|
|
605
|
+
});
|
|
602
606
|
}
|
|
603
607
|
|
|
604
608
|
static findLastDocumentForUrl<T extends Lantern.NetworkRequest>(records: T[], resourceUrl: string): T|undefined {
|
|
@@ -48,6 +48,7 @@ export enum EventKeyType {
|
|
|
48
48
|
SYNTHETIC_EVENT = 's',
|
|
49
49
|
PROFILE_CALL = 'p',
|
|
50
50
|
LEGACY_TIMELINE_FRAME = 'l',
|
|
51
|
+
LAYOUT_SHIFT_CLUSTER = 'c',
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
/**
|
|
@@ -141,7 +142,8 @@ export type RawEventKey = `${EventKeyType.RAW_EVENT}-${number}`;
|
|
|
141
142
|
export type SyntheticEventKey = `${EventKeyType.SYNTHETIC_EVENT}-${number}`;
|
|
142
143
|
export type ProfileCallKey = `${EventKeyType.PROFILE_CALL}-${ProcessID}-${ThreadID}-${SampleIndex}-${Protocol.integer}`;
|
|
143
144
|
export type LegacyTimelineFrameKey = `${EventKeyType.LEGACY_TIMELINE_FRAME}-${number}`;
|
|
144
|
-
export type
|
|
145
|
+
export type LayoutShiftClusterKey = `${EventKeyType.LAYOUT_SHIFT_CLUSTER}-${number}`;
|
|
146
|
+
export type SerializableKey = RawEventKey|ProfileCallKey|SyntheticEventKey|LegacyTimelineFrameKey|LayoutShiftClusterKey;
|
|
145
147
|
|
|
146
148
|
/** Serializable keys values objects contain data that maps the keys to original Trace Events **/
|
|
147
149
|
export interface RawEventKeyValues {
|
|
@@ -167,8 +169,14 @@ export interface LegacyTimelineFrameKeyValues {
|
|
|
167
169
|
rawIndex: number;
|
|
168
170
|
}
|
|
169
171
|
|
|
170
|
-
export
|
|
171
|
-
|
|
172
|
+
export interface LayoutShiftClusterKeyValues {
|
|
173
|
+
type: EventKeyType.LAYOUT_SHIFT_CLUSTER;
|
|
174
|
+
// The raw event index of the first layout shift in the cluster.
|
|
175
|
+
rawIndex: number;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export type SerializableKeyValues = RawEventKeyValues|ProfileCallKeyValues|SyntheticEventKeyValues|
|
|
179
|
+
LegacyTimelineFrameKeyValues|LayoutShiftClusterKeyValues;
|
|
172
180
|
|
|
173
181
|
export interface Modifications {
|
|
174
182
|
entriesModifications: {
|
|
@@ -291,6 +299,15 @@ export function traceEventKeyToValues(key: SerializableKey): SerializableKeyValu
|
|
|
291
299
|
rawIndex: parseInt(parts[1], 10),
|
|
292
300
|
};
|
|
293
301
|
}
|
|
302
|
+
case EventKeyType.LAYOUT_SHIFT_CLUSTER: {
|
|
303
|
+
if (parts.length !== 2 || Number.isNaN(parseInt(parts[1], 10))) {
|
|
304
|
+
throw new Error(`Invalid LayoutShiftCluster Key: ${key}`);
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
type,
|
|
308
|
+
rawIndex: parseInt(parts[1], 10),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
294
311
|
|
|
295
312
|
default:
|
|
296
313
|
throw new Error(`Unknown trace event key: ${key}`);
|
|
@@ -1080,10 +1080,15 @@ export const NO_NAVIGATION = 'NO_NAVIGATION';
|
|
|
1080
1080
|
export type NavigationId = string;
|
|
1081
1081
|
|
|
1082
1082
|
/**
|
|
1083
|
-
* This is a synthetic Layout shift cluster
|
|
1084
|
-
*
|
|
1083
|
+
* This is a synthetic Layout shift cluster: a session window of layout shifts.
|
|
1084
|
+
*
|
|
1085
|
+
* Do not extend the SyntheticBased interface because a cluster is built from
|
|
1086
|
+
* many layout shifts and doesn't have a raw trace event of its own. For the
|
|
1087
|
+
* same reason, clusters are not registered with SyntheticEventsManager. Use
|
|
1088
|
+
* `worstShiftEvent` to find the layout shift with the highest score in the
|
|
1089
|
+
* cluster.
|
|
1085
1090
|
*/
|
|
1086
|
-
export interface SyntheticLayoutShiftCluster extends
|
|
1091
|
+
export interface SyntheticLayoutShiftCluster extends Event {
|
|
1087
1092
|
name: 'SyntheticLayoutShiftCluster';
|
|
1088
1093
|
clusterWindow: TraceWindowMicro;
|
|
1089
1094
|
clusterCumulativeScore: number;
|
|
@@ -62,6 +62,10 @@ const AI_ASSISTANCE_HELP =
|
|
|
62
62
|
'https://developer.chrome.com/docs/devtools/ai-assistance' as Platform.DevToolsPath.UrlString;
|
|
63
63
|
const WALKTHROUGH_SIDEBAR_BREAKPOINT = 700;
|
|
64
64
|
const WALKTHROUGH_SIDEBAR_INITIAL_WIDTH = 400;
|
|
65
|
+
// Ignores approvals that arrive within this window after a permission prompt appears, so input meant for something
|
|
66
|
+
// else (such as the second click of a double-click on the previous prompt) cannot approve it. The value matches the
|
|
67
|
+
// 500 ms double-click interval that Chromium's InputEventActivationProtector uses for dialog buttons.
|
|
68
|
+
const PERMISSION_PROMPT_INPUT_PROTECTION_MS = 500;
|
|
65
69
|
|
|
66
70
|
const UIStrings = {
|
|
67
71
|
/**
|
|
@@ -594,6 +598,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
594
598
|
#serverSideLoggingEnabled = isAiAssistanceServerSideLoggingEnabled();
|
|
595
599
|
#aiAssistanceEnabledSetting: AiAssistanceModel.AiSetting.AiSetting<boolean>;
|
|
596
600
|
#changeManager = new AiAssistanceModel.ChangeManager.ChangeManager();
|
|
601
|
+
#alwaysAllowedTools =
|
|
602
|
+
new AiAssistanceModel.AlwaysAllowedTools.AlwaysAllowedTools(Common.Settings.Settings.instance());
|
|
597
603
|
#mutex = new Common.Mutex.Mutex();
|
|
598
604
|
|
|
599
605
|
#conversation?: AiAssistanceModel.AiConversation.AiConversation;
|
|
@@ -982,6 +988,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
982
988
|
isReadOnly: false,
|
|
983
989
|
aidaClient: this.#aidaClient,
|
|
984
990
|
changeManager: this.#changeManager,
|
|
991
|
+
alwaysAllowedTools: this.#alwaysAllowedTools,
|
|
985
992
|
performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
|
|
986
993
|
onInspectElement: this.#handleInspectElement.bind(this),
|
|
987
994
|
networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
|
|
@@ -1012,6 +1019,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1012
1019
|
isReadOnly: false,
|
|
1013
1020
|
aidaClient: this.#aidaClient,
|
|
1014
1021
|
changeManager: this.#changeManager,
|
|
1022
|
+
alwaysAllowedTools: this.#alwaysAllowedTools,
|
|
1015
1023
|
performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
|
|
1016
1024
|
onInspectElement: this.#handleInspectElement.bind(this),
|
|
1017
1025
|
networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
|
|
@@ -1519,6 +1527,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1519
1527
|
isReadOnly: false,
|
|
1520
1528
|
aidaClient: this.#aidaClient,
|
|
1521
1529
|
changeManager: this.#changeManager,
|
|
1530
|
+
alwaysAllowedTools: this.#alwaysAllowedTools,
|
|
1522
1531
|
performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
|
|
1523
1532
|
onInspectElement: this.#handleInspectElement.bind(this),
|
|
1524
1533
|
networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
|
|
@@ -1914,6 +1923,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1914
1923
|
step = stepForCall(data.callId);
|
|
1915
1924
|
const approvalStep = step;
|
|
1916
1925
|
approvalStep.code ??= data.code;
|
|
1926
|
+
const promptShownAt = performance.now();
|
|
1917
1927
|
approvalStep.state = {
|
|
1918
1928
|
type: 'needs_approval',
|
|
1919
1929
|
sideEffectDialog: {
|
|
@@ -1921,6 +1931,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1921
1931
|
permissionPrompt: data.permissionPrompt,
|
|
1922
1932
|
permissionTitle: data.permissionTitle,
|
|
1923
1933
|
onAnswer: (decision: AiAssistanceModel.Tool.PermissionDecision) => {
|
|
1934
|
+
if (decision !== AiAssistanceModel.Tool.PermissionDecision.REJECT &&
|
|
1935
|
+
performance.now() - promptShownAt < PERMISSION_PROMPT_INPUT_PROTECTION_MS) {
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1924
1938
|
data.confirm(decision);
|
|
1925
1939
|
approvalStep.state = {type: 'completed'};
|
|
1926
1940
|
this.requestUpdate();
|
|
@@ -117,7 +117,7 @@ Each `Step` has a `state` (`StepState` in `components/ChatMessage.ts`):
|
|
|
117
117
|
| State | Set when | Badge |
|
|
118
118
|
| :--- | :--- | :--- |
|
|
119
119
|
| `in_progress` | `QUERYING` creates the step. | A spinner if the step is the last step. Otherwise, a checkmark. |
|
|
120
|
-
| `needs_approval` | A `SIDE_EFFECT` event asks the user to approve a tool call. The state holds the approval dialog. | A pause icon, with the approval prompt in the step. Only the last step can be in this state. |
|
|
120
|
+
| `needs_approval` | A `SIDE_EFFECT` event asks the user to approve a tool call. The state holds the approval dialog. The panel ignores allow decisions that arrive within 500 ms of the prompt appearing; rejections always go through. | A pause icon, with the approval prompt in the step. Only the last step can be in this state. |
|
|
121
121
|
| `canceled` | An `ACTION` with `canceled: true` arrives because the user denied the tool call, or the user aborts the run while this is the last step. | A cross. |
|
|
122
122
|
| `completed` | A `CONTEXT`, `THOUGHT`, `ACTION`, `CONTEXT_CHANGE` or `ANSWER` event arrives, or the user answers the approval prompt. | A checkmark. |
|
|
123
123
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as Root from '../../core/root/root.js';
|
|
8
|
-
import * as AiAssistanceModel from '../../models/
|
|
8
|
+
import * as AiAssistanceModel from '../../models/ai-utils/ai-utils.js';
|
|
9
9
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
10
10
|
import * as SettingUIRegistration from '../../ui/settings/settings.js';
|
|
11
11
|
|
|
@@ -12,6 +12,8 @@ export * as ChatMessage from './components/ChatMessage.js';
|
|
|
12
12
|
export * as ExploreWidget from './components/ExploreWidget.js';
|
|
13
13
|
export * as ExportForAgentsDialog from './components/ExportForAgentsDialog.js';
|
|
14
14
|
export * as OptInChangeDialog from './components/OptInChangeDialog.js';
|
|
15
|
+
export * as PermissionPrompt from './components/PermissionPrompt.js';
|
|
16
|
+
export * as RelevantDataDisclaimer from './components/RelevantDataDisclaimer.js';
|
|
15
17
|
export * as DisabledWidget from './components/DisabledWidget.js';
|
|
16
18
|
export * as WalkthroughUtils from './components/WalkthroughUtils.js';
|
|
17
19
|
export * as WalkthroughView from './components/WalkthroughView.js';
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import '../../../ui/components/tooltips/tooltips.js';
|
|
6
|
-
|
|
7
5
|
import type * as Host from '../../../core/host/host.js';
|
|
8
6
|
import * as i18n from '../../../core/i18n/i18n.js';
|
|
9
7
|
import type * as Platform from '../../../core/platform/platform.js';
|
|
@@ -21,6 +19,7 @@ import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
|
21
19
|
|
|
22
20
|
import chatInputStyles from './chatInput.css.js';
|
|
23
21
|
import * as ImageResize from './ImageResize.js';
|
|
22
|
+
import {renderRelevantDataDisclaimer} from './RelevantDataDisclaimer.js';
|
|
24
23
|
|
|
25
24
|
const {html, Directives: {createRef, ref}} = Lit;
|
|
26
25
|
const {widget} = UI.Widget;
|
|
@@ -34,10 +33,6 @@ const UIStrings = {
|
|
|
34
33
|
* @description Label added to the button that reveals the selected context item in DevTools.
|
|
35
34
|
*/
|
|
36
35
|
revealContextDescription: 'Reveal the selected context item in DevTools',
|
|
37
|
-
/**
|
|
38
|
-
* @description The footer disclaimer that links to more information about the AI feature.
|
|
39
|
-
*/
|
|
40
|
-
learnAbout: 'Learn about AI in DevTools',
|
|
41
36
|
} as const;
|
|
42
37
|
|
|
43
38
|
/*
|
|
@@ -207,45 +202,12 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
207
202
|
disabled: input.isTextInputDisabled,
|
|
208
203
|
});
|
|
209
204
|
|
|
210
|
-
const
|
|
205
|
+
const renderDisclaimer = (tooltipId: string): Lit.LitTemplate => {
|
|
211
206
|
const classes = Lit.Directives.classMap({
|
|
212
207
|
'chat-input-disclaimer': true,
|
|
213
208
|
'hide-divider': !input.isLoading && input.blockedByCrossOrigin,
|
|
214
209
|
});
|
|
215
|
-
|
|
216
|
-
return html`
|
|
217
|
-
<div class=${classes}>
|
|
218
|
-
<button
|
|
219
|
-
class="link"
|
|
220
|
-
role="link"
|
|
221
|
-
aria-details=${tooltipId}
|
|
222
|
-
jslog=${VisualLogging.link('open-ai-settings').track({
|
|
223
|
-
click: true,
|
|
224
|
-
})}
|
|
225
|
-
@click=${(ev: Event) => {
|
|
226
|
-
ev.preventDefault();
|
|
227
|
-
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
228
|
-
}}
|
|
229
|
-
>${lockedString('Relevant data')}</button> ${lockedString('is sent to Google')}
|
|
230
|
-
<devtools-tooltip
|
|
231
|
-
id=${tooltipId}
|
|
232
|
-
variant="rich"
|
|
233
|
-
><div class="info-tooltip-container">
|
|
234
|
-
${input.disclaimerText}
|
|
235
|
-
<button
|
|
236
|
-
class="link tooltip-link"
|
|
237
|
-
role="link"
|
|
238
|
-
jslog=${VisualLogging.link('open-ai-settings').track({
|
|
239
|
-
click: true,
|
|
240
|
-
})}
|
|
241
|
-
@click=${() => {
|
|
242
|
-
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
243
|
-
}}>${i18nString(UIStrings.learnAbout)}
|
|
244
|
-
</button>
|
|
245
|
-
</div></devtools-tooltip>
|
|
246
|
-
</div>
|
|
247
|
-
`;
|
|
248
|
-
// clang-format on
|
|
210
|
+
return html`<div class=${classes}>${renderRelevantDataDisclaimer(tooltipId, input.disclaimerText)}</div>`;
|
|
249
211
|
};
|
|
250
212
|
|
|
251
213
|
// clang-format off
|
|
@@ -413,7 +375,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
413
375
|
</div>
|
|
414
376
|
<div class="chat-input-actions-right">
|
|
415
377
|
<div class="chat-input-disclaimer-container">
|
|
416
|
-
${
|
|
378
|
+
${renderDisclaimer(RELEVANT_DATA_LINK_CHAT_ID)}
|
|
417
379
|
</div>
|
|
418
380
|
${(input.multimodalInputEnabled && !input.blockedByCrossOrigin) ?
|
|
419
381
|
html`
|
|
@@ -503,7 +465,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
503
465
|
})}
|
|
504
466
|
jslog=${VisualLogging.section('footer')}
|
|
505
467
|
>
|
|
506
|
-
${
|
|
468
|
+
${renderDisclaimer(RELEVANT_DATA_LINK_FOOTER_ID)}
|
|
507
469
|
</footer>
|
|
508
470
|
`, target);
|
|
509
471
|
// clang-format on
|
|
@@ -47,7 +47,6 @@ const {html, Directives: {ref, ifDefined}} = Lit;
|
|
|
47
47
|
const lockedString = i18n.i18n.lockedString;
|
|
48
48
|
const {widget} = UI.Widget;
|
|
49
49
|
|
|
50
|
-
const REPORT_URL = 'https://crbug.com/508304827' as Platform.DevToolsPath.UrlString;
|
|
51
50
|
const SCROLL_ROUNDING_OFFSET = 1;
|
|
52
51
|
|
|
53
52
|
/*
|
|
@@ -131,26 +130,6 @@ const UIStringsNotTranslate = {
|
|
|
131
130
|
* @description Button text that cancels code execution that may affect the page.
|
|
132
131
|
*/
|
|
133
132
|
declineActionRequestApproval: 'Cancel',
|
|
134
|
-
/**
|
|
135
|
-
* @description Button text in the permission prompt that skips the tool call.
|
|
136
|
-
*/
|
|
137
|
-
skipToolCall: 'Skip',
|
|
138
|
-
/**
|
|
139
|
-
* @description Button text in the permission prompt that allows the tool call once.
|
|
140
|
-
*/
|
|
141
|
-
allowThisTime: 'Yes, allow this time',
|
|
142
|
-
/**
|
|
143
|
-
* @description Button text in the permission prompt that allows the tool call now and in the future.
|
|
144
|
-
*/
|
|
145
|
-
allowAlways: 'Yes, always allow',
|
|
146
|
-
/**
|
|
147
|
-
* @description Fallback title of the permission prompt when the tool has no title.
|
|
148
|
-
*/
|
|
149
|
-
allowThisAction: 'Allow this action?',
|
|
150
|
-
/**
|
|
151
|
-
* @description Footer of the permission prompt.
|
|
152
|
-
*/
|
|
153
|
-
relevantDataIsSentToGoogle: 'Relevant data is sent to Google. Change permissions in settings at any time.',
|
|
154
133
|
/**
|
|
155
134
|
* @description The fallback text when a step has no title yet
|
|
156
135
|
*/
|
|
@@ -895,105 +874,32 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
895
874
|
}
|
|
896
875
|
|
|
897
876
|
function renderSideEffectStepsUI(input: ChatMessageViewInput, steps: Step[]): Lit.LitTemplate {
|
|
898
|
-
|
|
877
|
+
// With the natural language interface a step that needs approval is
|
|
878
|
+
// rendered by ChatView as a permission prompt in place of the chat input
|
|
879
|
+
// (see `renderPermissionPrompt`), so it is skipped here.
|
|
880
|
+
const sideEffectSteps = steps.filter(
|
|
881
|
+
s => (s.state.type === 'needs_approval' && !AiAssistanceModel.AiUtils.isNaturalLanguageInterfaceEnabled()));
|
|
899
882
|
if (sideEffectSteps.length === 0) {
|
|
900
883
|
return Lit.nothing;
|
|
901
884
|
}
|
|
902
|
-
//
|
|
903
|
-
//
|
|
904
|
-
|
|
885
|
+
// Key each prompt by its step so that a new prompt always gets new DOM.
|
|
886
|
+
// Without the key, Lit reuses the previous prompt's buttons when one prompt
|
|
887
|
+
// replaces another in a single render, and keyboard focus on the previous
|
|
888
|
+
// approve button would carry over to the new prompt.
|
|
905
889
|
// clang-format off
|
|
906
890
|
return html`
|
|
907
|
-
${
|
|
891
|
+
${Lit.Directives.repeat(sideEffectSteps, step => step, step => html`
|
|
908
892
|
<div class="side-effect-container">
|
|
909
|
-
${
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
isLast: true,
|
|
915
|
-
})}
|
|
893
|
+
${renderStep({
|
|
894
|
+
step,
|
|
895
|
+
markdownRenderer: input.markdownRenderer,
|
|
896
|
+
isLast: true,
|
|
897
|
+
})}
|
|
916
898
|
</div> `)}
|
|
917
899
|
`;
|
|
918
900
|
// clang-format on
|
|
919
901
|
}
|
|
920
902
|
|
|
921
|
-
/**
|
|
922
|
-
* Renders the permission prompt for a step that needs approval. Used when
|
|
923
|
-
* `AiUtils.isNaturalLanguageInterfaceEnabled()` is on; otherwise
|
|
924
|
-
* `renderSideEffectStepsUI` falls back to `renderStep`, which shows the
|
|
925
|
-
* legacy Allow / Deny buttons inside the `renderSideEffectConfirmationUi`.
|
|
926
|
-
*
|
|
927
|
-
* A separate UI is needed because the natural language interface runs tools
|
|
928
|
-
* that need richer consent than "run this code?": a tool-specific title and
|
|
929
|
-
* description, and an "Allow always" option (`sideEffectDialog.permissionPrompt`).
|
|
930
|
-
* It is a standalone card rather than a collapsible step so the user sees the
|
|
931
|
-
* question without expanding anything.
|
|
932
|
-
*
|
|
933
|
-
* TODO(b/516828269): Remove `renderSideEffectConfirmationUi` once the natural
|
|
934
|
-
* language interface launches.
|
|
935
|
-
*/
|
|
936
|
-
function renderPermissionPrompt(step: Step): Lit.LitTemplate {
|
|
937
|
-
if (step.state.type !== 'needs_approval') {
|
|
938
|
-
return Lit.nothing;
|
|
939
|
-
}
|
|
940
|
-
const dialog = step.state.sideEffectDialog;
|
|
941
|
-
const title = dialog.permissionTitle ?? lockedString(UIStringsNotTranslate.allowThisAction);
|
|
942
|
-
|
|
943
|
-
const description =
|
|
944
|
-
dialog.description ? html`<p class="permission-prompt-description">${dialog.description}</p>` : Lit.nothing;
|
|
945
|
-
|
|
946
|
-
const code = step.code ? html`<devtools-code-block
|
|
947
|
-
class="permission-prompt-code"
|
|
948
|
-
.code=${step.code.trim()}
|
|
949
|
-
.codeLang=${'js'}
|
|
950
|
-
.displayNotice=${true}
|
|
951
|
-
.header=${lockedString(UIStringsNotTranslate.codeToExecute)}
|
|
952
|
-
></devtools-code-block>` :
|
|
953
|
-
Lit.nothing;
|
|
954
|
-
|
|
955
|
-
const allowAlwaysButton = dialog.permissionPrompt === AiAssistanceModel.Tool.PermissionPrompt.ALLOW_ONCE_OR_ALWAYS ?
|
|
956
|
-
html`<devtools-button
|
|
957
|
-
.data=${{
|
|
958
|
-
variant: Buttons.Button.Variant.OUTLINED,
|
|
959
|
-
jslogContext: 'always-allow-execute-code',
|
|
960
|
-
} as Buttons.Button.ButtonData}
|
|
961
|
-
@click=${() => dialog.onAnswer(AiAssistanceModel.Tool.PermissionDecision.ALLOW_ALWAYS)}
|
|
962
|
-
>${lockedString(UIStringsNotTranslate.allowAlways)}</devtools-button>` :
|
|
963
|
-
Lit.nothing;
|
|
964
|
-
|
|
965
|
-
// clang-format off
|
|
966
|
-
return html`
|
|
967
|
-
<div class="permission-prompt"
|
|
968
|
-
jslog=${VisualLogging.section('side-effect-confirmation')}>
|
|
969
|
-
<div class="permission-prompt-header">
|
|
970
|
-
<devtools-icon name="lock"></devtools-icon>
|
|
971
|
-
<h3 class="permission-prompt-title">${title}</h3>
|
|
972
|
-
</div>
|
|
973
|
-
${description}
|
|
974
|
-
${code}
|
|
975
|
-
<p class="permission-prompt-footer">${lockedString(UIStringsNotTranslate.relevantDataIsSentToGoogle)}</p>
|
|
976
|
-
<div class="permission-prompt-buttons">
|
|
977
|
-
<devtools-button
|
|
978
|
-
.data=${{
|
|
979
|
-
variant: Buttons.Button.Variant.TEXT,
|
|
980
|
-
jslogContext: 'decline-execute-code',
|
|
981
|
-
} as Buttons.Button.ButtonData}
|
|
982
|
-
@click=${() => dialog.onAnswer(AiAssistanceModel.Tool.PermissionDecision.REJECT)}
|
|
983
|
-
>${lockedString(UIStringsNotTranslate.skipToolCall)}</devtools-button>
|
|
984
|
-
${allowAlwaysButton}
|
|
985
|
-
<devtools-button
|
|
986
|
-
.data=${{
|
|
987
|
-
variant: Buttons.Button.Variant.PRIMARY,
|
|
988
|
-
jslogContext: 'accept-execute-code',
|
|
989
|
-
} as Buttons.Button.ButtonData}
|
|
990
|
-
@click=${() => dialog.onAnswer(AiAssistanceModel.Tool.PermissionDecision.ALLOW_ONCE)}
|
|
991
|
-
>${lockedString(UIStringsNotTranslate.allowThisTime)}</devtools-button>
|
|
992
|
-
</div>
|
|
993
|
-
</div>`;
|
|
994
|
-
// clang-format on
|
|
995
|
-
}
|
|
996
|
-
|
|
997
903
|
function renderStepBadge({step, isLast}: {
|
|
998
904
|
step: Step,
|
|
999
905
|
isLast: boolean,
|
|
@@ -2251,44 +2157,43 @@ export class ChatMessage extends UI.Widget.Widget {
|
|
|
2251
2157
|
override performUpdate(): Promise<void>|void {
|
|
2252
2158
|
const message =
|
|
2253
2159
|
this.message.entity === ChatMessageEntity.MODEL ? getDeduplicatedWidgetsMessage(this.message) : this.message;
|
|
2254
|
-
this.#view(
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
this.#viewOutput, this.contentElement);
|
|
2160
|
+
this.#view({
|
|
2161
|
+
message,
|
|
2162
|
+
isLoading: this.isLoading,
|
|
2163
|
+
isReadOnly: this.isReadOnly,
|
|
2164
|
+
canShowFeedbackForm: this.canShowFeedbackForm,
|
|
2165
|
+
markdownRenderer: this.markdownRenderer,
|
|
2166
|
+
isLastMessage: this.isLastMessage,
|
|
2167
|
+
isFirstMessage: this.isFirstMessage,
|
|
2168
|
+
prompt: this.prompt,
|
|
2169
|
+
onSuggestionClick: this.onSuggestionClick,
|
|
2170
|
+
onRatingClick: this.#handleRateClick.bind(this),
|
|
2171
|
+
onReportClick: () => UIHelpers.openInNewTab(AiAssistanceModel.AiUtils.REPORT_LEGAL_ISSUE_URL),
|
|
2172
|
+
onCopyResponseClick: () => {
|
|
2173
|
+
if (this.message.entity === ChatMessageEntity.MODEL) {
|
|
2174
|
+
this.onCopyResponseClick(this.message);
|
|
2175
|
+
}
|
|
2176
|
+
},
|
|
2177
|
+
onExportClick: this.onExportClick,
|
|
2178
|
+
scrollSuggestionsScrollContainer: this.#scrollSuggestionsScrollContainer.bind(this),
|
|
2179
|
+
onSuggestionsScrollOrResize: this.#handleSuggestionsScrollOrResize.bind(this),
|
|
2180
|
+
onSubmit: this.#handleSubmit.bind(this),
|
|
2181
|
+
onClose: this.#handleClose.bind(this),
|
|
2182
|
+
onInputChange: this.#handleInputChange.bind(this),
|
|
2183
|
+
isSubmitButtonDisabled: this.#isSubmitButtonDisabled,
|
|
2184
|
+
// Props for actions logic
|
|
2185
|
+
showActions: !(this.isLastMessage && this.isLoading),
|
|
2186
|
+
showRateButtons: this.message.entity === ChatMessageEntity.MODEL && !!this.message.rpcId,
|
|
2187
|
+
suggestions: (this.isLastMessage && this.message.entity === ChatMessageEntity.MODEL && !this.isReadOnly &&
|
|
2188
|
+
this.message.parts.at(-1)?.type === 'answer') ?
|
|
2189
|
+
(this.message.parts.at(-1) as AnswerPart).suggestions :
|
|
2190
|
+
undefined,
|
|
2191
|
+
currentRating: this.#currentRating,
|
|
2192
|
+
isShowingFeedbackForm: this.#isShowingFeedbackForm,
|
|
2193
|
+
onFeedbackSubmit: this.onFeedbackSubmit,
|
|
2194
|
+
walkthrough: this.walkthrough,
|
|
2195
|
+
},
|
|
2196
|
+
this.#viewOutput, this.contentElement);
|
|
2292
2197
|
|
|
2293
2198
|
if (this.#viewOutput.suggestionsScrollContainer && !this.#isObservingSuggestions) {
|
|
2294
2199
|
this.#suggestionsResizeObserver.observe(this.#viewOutput.suggestionsScrollContainer);
|