chrome-devtools-frontend 1.0.1541552 → 1.0.1543082
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/docs/get_the_code.md +9 -0
- package/front_end/Tests.js +1 -0
- package/front_end/core/common/Settings.ts +38 -15
- package/front_end/core/host/InspectorFrontendHost.ts +0 -3
- package/front_end/core/host/UserMetrics.ts +5 -0
- package/front_end/core/root/Runtime.ts +0 -10
- package/front_end/core/sdk/IOModel.ts +1 -4
- package/front_end/core/sdk/NetworkManager.ts +0 -7
- package/front_end/core/sdk/NetworkRequest.ts +0 -10
- package/front_end/core/sdk/ServerSentEventsProtocol.ts +4 -0
- package/front_end/entrypoints/inspector_main/RenderingOptions.ts +5 -5
- package/front_end/entrypoints/main/MainImpl.ts +6 -3
- package/front_end/entrypoints/main/main-meta.ts +1 -5
- package/front_end/foundation/Universe.ts +2 -10
- package/front_end/generated/Deprecation.ts +0 -14
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +42 -42
- package/front_end/generated/protocol.ts +0 -1
- package/front_end/models/ai_assistance/BuiltInAi.ts +13 -7
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +72 -31
- package/front_end/models/bindings/CompilerScriptMapping.ts +3 -2
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +3 -1
- package/front_end/models/har/Importer.ts +14 -0
- package/front_end/models/issues_manager/IssuesManager.ts +0 -5
- package/front_end/models/javascript_metadata/NativeFunctions.js +0 -4
- package/front_end/models/trace/handlers/ScriptsHandler.ts +26 -0
- package/front_end/models/trace/types/TraceEvents.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +117 -103
- package/front_end/panels/ai_assistance/components/ChatView.ts +7 -31
- package/front_end/panels/ai_assistance/components/chatView.css +1 -1
- package/front_end/panels/application/components/BackForwardCacheView.ts +12 -9
- package/front_end/panels/console/ConsoleInsightTeaser.ts +5 -0
- package/front_end/panels/console/ConsolePrompt.ts +9 -2
- package/front_end/panels/console/ConsoleView.ts +3 -0
- package/front_end/panels/network/NetworkDataGridNode.ts +0 -7
- package/front_end/panels/network/NetworkLogView.ts +1 -45
- package/front_end/panels/security/SecurityPanel.ts +0 -2
- package/front_end/panels/security/SecurityPanelSidebar.ts +0 -16
- package/front_end/panels/security/security.ts +0 -2
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +17 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/expandable_list/ExpandableList.docs.ts +30 -0
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +0 -4
- package/front_end/ui/components/markdown_view/MarkdownView.docs.ts +95 -0
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +246 -13
- package/front_end/ui/components/text_editor/config.ts +1 -1
- package/front_end/ui/legacy/Widget.ts +13 -4
- package/front_end/ui/legacy/components/utils/Linkifier.ts +45 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +11 -0
- package/package.json +1 -1
- package/front_end/models/issues_manager/UserReidentificationIssue.ts +0 -72
- package/front_end/models/issues_manager/descriptions/userReidentificationBlocked.md +0 -5
- package/front_end/panels/security/IPProtectionTreeElement.ts +0 -21
- package/front_end/panels/security/IPProtectionView.ts +0 -287
- package/front_end/ui/components/docs/expandable_list/basic.html +0 -24
- package/front_end/ui/components/docs/expandable_list/basic.ts +0 -30
- package/front_end/ui/components/docs/markdown_image/basic.html +0 -19
- package/front_end/ui/components/docs/markdown_image/basic.ts +0 -38
- package/front_end/ui/components/docs/markdown_link/basic.html +0 -17
- package/front_end/ui/components/docs/markdown_link/basic.ts +0 -19
- package/front_end/ui/components/docs/markdown_view/basic.html +0 -25
- package/front_end/ui/components/docs/markdown_view/basic.ts +0 -67
- package/front_end/ui/components/docs/markdown_view/code-block.html +0 -30
- package/front_end/ui/components/docs/markdown_view/code-block.ts +0 -71
- package/front_end/ui/components/docs/text_prompt/basic.html +0 -35
- package/front_end/ui/components/docs/text_prompt/basic.ts +0 -19
|
@@ -302,11 +302,17 @@ export const enum ViewState {
|
|
|
302
302
|
EXPLORE_VIEW = 'explore-view'
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
|
|
306
|
-
state: ViewState
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
305
|
+
type PanelViewInput = {
|
|
306
|
+
state: ViewState.CHAT_VIEW,
|
|
307
|
+
props: ChatViewProps,
|
|
308
|
+
}|{
|
|
309
|
+
state: ViewState.DISABLED_VIEW,
|
|
310
|
+
props: {aidaAvailability: Host.AidaClient.AidaAccessPreconditions},
|
|
311
|
+
}|{
|
|
312
|
+
state: ViewState.EXPLORE_VIEW,
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
export type ViewInput = ToolbarViewInput&PanelViewInput;
|
|
310
316
|
export interface PanelViewOutput {
|
|
311
317
|
chatView?: ChatView;
|
|
312
318
|
}
|
|
@@ -389,7 +395,7 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
389
395
|
switch (input.state) {
|
|
390
396
|
case ViewState.CHAT_VIEW:
|
|
391
397
|
return html`<devtools-ai-chat-view
|
|
392
|
-
.props=${input}
|
|
398
|
+
.props=${input.props}
|
|
393
399
|
${Lit.Directives.ref((el: Element | undefined) => {
|
|
394
400
|
if (!el || !(el instanceof ChatView)) {
|
|
395
401
|
return;
|
|
@@ -407,9 +413,7 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
407
413
|
case ViewState.DISABLED_VIEW:
|
|
408
414
|
return html`<devtools-widget
|
|
409
415
|
class="fill-panel"
|
|
410
|
-
.widgetConfig=${UI.Widget.widgetConfig(DisabledWidget,
|
|
411
|
-
aidaAvailability: input.aidaAvailability,
|
|
412
|
-
})}
|
|
416
|
+
.widgetConfig=${UI.Widget.widgetConfig(DisabledWidget, input.props)}
|
|
413
417
|
></devtools-widget>`;
|
|
414
418
|
}
|
|
415
419
|
}
|
|
@@ -551,19 +555,73 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
551
555
|
AiAssistanceModel.AiHistoryStorage.Events.HISTORY_DELETED, this.#onHistoryDeleted, this);
|
|
552
556
|
}
|
|
553
557
|
|
|
554
|
-
#
|
|
558
|
+
async #getPanelViewInput(): Promise<PanelViewInput> {
|
|
555
559
|
const blockedByAge = Root.Runtime.hostConfig.aidaAvailability?.blockedByAge === true;
|
|
556
560
|
|
|
557
561
|
if (this.#aidaAvailability !== Host.AidaClient.AidaAccessPreconditions.AVAILABLE ||
|
|
558
562
|
!this.#aiAssistanceEnabledSetting?.getIfNotDisabled() || blockedByAge) {
|
|
559
|
-
return
|
|
563
|
+
return {
|
|
564
|
+
state: ViewState.DISABLED_VIEW,
|
|
565
|
+
props: {
|
|
566
|
+
aidaAvailability: this.#aidaAvailability,
|
|
567
|
+
},
|
|
568
|
+
};
|
|
560
569
|
}
|
|
561
570
|
|
|
562
571
|
if (this.#conversation?.type) {
|
|
563
|
-
|
|
572
|
+
const emptyStateSuggestions = await getEmptyStateSuggestions(this.#selectedContext, this.#conversation);
|
|
573
|
+
const markdownRenderer = getMarkdownRenderer(this.#selectedContext, this.#conversation);
|
|
574
|
+
return {
|
|
575
|
+
state: ViewState.CHAT_VIEW,
|
|
576
|
+
props: {
|
|
577
|
+
blockedByCrossOrigin: this.#blockedByCrossOrigin,
|
|
578
|
+
isLoading: this.#isLoading,
|
|
579
|
+
messages: this.#messages,
|
|
580
|
+
selectedContext: this.#selectedContext,
|
|
581
|
+
conversationType: this.#conversation.type,
|
|
582
|
+
isReadOnly: this.#conversation.isReadOnly ?? false,
|
|
583
|
+
changeSummary: this.#getChangeSummary(),
|
|
584
|
+
inspectElementToggled: this.#toggleSearchElementAction?.toggled() ?? false,
|
|
585
|
+
userInfo: this.#userInfo,
|
|
586
|
+
canShowFeedbackForm: this.#serverSideLoggingEnabled,
|
|
587
|
+
multimodalInputEnabled: isAiAssistanceMultimodalInputEnabled() &&
|
|
588
|
+
this.#conversation.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
589
|
+
imageInput: this.#imageInput,
|
|
590
|
+
isTextInputDisabled: this.#isTextInputDisabled(),
|
|
591
|
+
emptyStateSuggestions,
|
|
592
|
+
inputPlaceholder: this.#getChatInputPlaceholder(),
|
|
593
|
+
disclaimerText: this.#getDisclaimerText(),
|
|
594
|
+
isTextInputEmpty: this.#isTextInputEmpty,
|
|
595
|
+
changeManager: this.#changeManager,
|
|
596
|
+
uploadImageInputEnabled: isAiAssistanceMultimodalUploadInputEnabled() &&
|
|
597
|
+
this.#conversation.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
598
|
+
markdownRenderer,
|
|
599
|
+
onTextSubmit: async (
|
|
600
|
+
text: string, imageInput?: Host.AidaClient.Part,
|
|
601
|
+
multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
|
|
602
|
+
this.#imageInput = undefined;
|
|
603
|
+
this.#isTextInputEmpty = true;
|
|
604
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
|
|
605
|
+
await this.#startConversation(text, imageInput, multimodalInputType);
|
|
606
|
+
},
|
|
607
|
+
onInspectElementClick: this.#handleSelectElementClick.bind(this),
|
|
608
|
+
onFeedbackSubmit: this.#handleFeedbackSubmit.bind(this),
|
|
609
|
+
onCancelClick: this.#cancel.bind(this),
|
|
610
|
+
onContextClick: this.#handleContextClick.bind(this),
|
|
611
|
+
onNewConversation: this.#handleNewChatRequest.bind(this),
|
|
612
|
+
onTakeScreenshot: isAiAssistanceMultimodalInputEnabled() ? this.#handleTakeScreenshot.bind(this) : undefined,
|
|
613
|
+
onRemoveImageInput: isAiAssistanceMultimodalInputEnabled() ? this.#handleRemoveImageInput.bind(this) :
|
|
614
|
+
undefined,
|
|
615
|
+
onCopyResponseClick: this.#onCopyResponseClick.bind(this),
|
|
616
|
+
onTextInputChange: this.#handleTextInputChange.bind(this),
|
|
617
|
+
onLoadImage: isAiAssistanceMultimodalUploadInputEnabled() ? this.#handleLoadImage.bind(this) : undefined,
|
|
618
|
+
}
|
|
619
|
+
};
|
|
564
620
|
}
|
|
565
621
|
|
|
566
|
-
return
|
|
622
|
+
return {
|
|
623
|
+
state: ViewState.EXPLORE_VIEW,
|
|
624
|
+
};
|
|
567
625
|
}
|
|
568
626
|
|
|
569
627
|
#getAiAssistanceEnabledSetting(): Common.Settings.Setting<boolean>|undefined {
|
|
@@ -616,15 +674,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
616
674
|
}
|
|
617
675
|
}
|
|
618
676
|
|
|
619
|
-
|
|
620
|
-
// there isn't any active conversation.
|
|
621
|
-
#selectDefaultAgentIfNeeded(): void {
|
|
622
|
-
// If there already is an agent and if it is not empty,
|
|
623
|
-
// we don't automatically change the agent. In addition to this,
|
|
624
|
-
// we don't change the current agent when there is a message in flight.
|
|
625
|
-
if ((this.#conversationAgent && this.#conversation && !this.#conversation.isEmpty) || this.#isLoading) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
677
|
+
#getDefaultConversationType(): AiAssistanceModel.AiHistoryStorage.ConversationType|undefined {
|
|
628
678
|
const {hostConfig} = Root.Runtime;
|
|
629
679
|
const viewManager = UI.ViewManager.ViewManager.instance();
|
|
630
680
|
const isElementsPanelVisible = viewManager.isViewVisible('elements');
|
|
@@ -643,12 +693,24 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
643
693
|
targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE;
|
|
644
694
|
}
|
|
645
695
|
|
|
696
|
+
return targetConversationType;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// We select the default agent based on the open panels if
|
|
700
|
+
// there isn't any active conversation.
|
|
701
|
+
#selectDefaultAgentIfNeeded(): void {
|
|
702
|
+
// If there already is an agent and if it is not empty,
|
|
703
|
+
// we don't automatically change the agent. In addition to this,
|
|
704
|
+
// we don't change the current agent when there is a message in flight.
|
|
705
|
+
if ((this.#conversationAgent && this.#conversation && !this.#conversation.isEmpty) || this.#isLoading) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
const targetConversationType = this.#getDefaultConversationType();
|
|
646
709
|
if (this.#conversation?.type === targetConversationType) {
|
|
647
710
|
// The above if makes sure even if we have an active agent it's empty
|
|
648
711
|
// So we can just reuse it
|
|
649
712
|
return;
|
|
650
713
|
}
|
|
651
|
-
|
|
652
714
|
const agent = targetConversationType ?
|
|
653
715
|
this.#conversationHandler.createAgent(targetConversationType, this.#changeManager) :
|
|
654
716
|
undefined;
|
|
@@ -671,9 +733,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
671
733
|
// create a new conversation along side it
|
|
672
734
|
if (opts?.agent) {
|
|
673
735
|
this.#conversation = new AiAssistanceModel.AiHistoryStorage.Conversation(
|
|
674
|
-
agentToConversationType(opts
|
|
736
|
+
agentToConversationType(opts.agent),
|
|
675
737
|
[],
|
|
676
|
-
opts
|
|
738
|
+
opts.agent.id,
|
|
677
739
|
false,
|
|
678
740
|
);
|
|
679
741
|
}
|
|
@@ -687,15 +749,21 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
687
749
|
// but conversation is
|
|
688
750
|
// update with history conversation
|
|
689
751
|
if (opts?.conversation) {
|
|
690
|
-
this.#conversation = opts
|
|
752
|
+
this.#conversation = opts.conversation;
|
|
691
753
|
}
|
|
692
754
|
}
|
|
693
755
|
|
|
694
756
|
if (!this.#conversationAgent && !this.#conversation) {
|
|
695
|
-
this.#
|
|
757
|
+
const conversationType = this.#getDefaultConversationType();
|
|
758
|
+
if (conversationType) {
|
|
759
|
+
const agent = this.#conversationHandler.createAgent(conversationType, this.#changeManager);
|
|
760
|
+
this.#updateConversationState({agent});
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
696
763
|
}
|
|
697
764
|
|
|
698
765
|
this.#onContextSelectionChanged();
|
|
766
|
+
|
|
699
767
|
this.requestUpdate();
|
|
700
768
|
}
|
|
701
769
|
|
|
@@ -879,67 +947,29 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
879
947
|
return this.#changeManager.formatChangesForPatching(this.#conversationAgent.id, /* includeSourceLocation= */ true);
|
|
880
948
|
}
|
|
881
949
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
950
|
+
#getToolbarInput(): ToolbarViewInput {
|
|
951
|
+
return {
|
|
952
|
+
isLoading: this.#isLoading,
|
|
953
|
+
showChatActions: this.#shouldShowChatActions(),
|
|
954
|
+
showActiveConversationActions: Boolean(this.#conversation && !this.#conversation.isEmpty),
|
|
955
|
+
onNewChatClick: this.#handleNewChatRequest.bind(this),
|
|
956
|
+
populateHistoryMenu: this.#populateHistoryMenu.bind(this),
|
|
957
|
+
onDeleteClick: this.#onDeleteClicked.bind(this),
|
|
958
|
+
onExportConversationClick: this.#onExportConversationClick.bind(this),
|
|
959
|
+
onHelpClick: () => {
|
|
960
|
+
UI.UIUtils.openInNewTab(AI_ASSISTANCE_HELP);
|
|
961
|
+
},
|
|
962
|
+
onSettingsClick: () => {
|
|
963
|
+
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
964
|
+
},
|
|
965
|
+
};
|
|
966
|
+
}
|
|
885
967
|
|
|
968
|
+
override async performUpdate(): Promise<void> {
|
|
886
969
|
this.view(
|
|
887
970
|
{
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
aidaAvailability: this.#aidaAvailability,
|
|
891
|
-
isLoading: this.#isLoading,
|
|
892
|
-
messages: this.#messages,
|
|
893
|
-
selectedContext: this.#selectedContext,
|
|
894
|
-
conversationType: this.#conversation?.type,
|
|
895
|
-
isReadOnly: this.#conversation?.isReadOnly ?? false,
|
|
896
|
-
changeSummary: this.#getChangeSummary(),
|
|
897
|
-
inspectElementToggled: this.#toggleSearchElementAction?.toggled() ?? false,
|
|
898
|
-
userInfo: this.#userInfo,
|
|
899
|
-
canShowFeedbackForm: this.#serverSideLoggingEnabled,
|
|
900
|
-
multimodalInputEnabled: isAiAssistanceMultimodalInputEnabled() &&
|
|
901
|
-
this.#conversation?.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
902
|
-
imageInput: this.#imageInput,
|
|
903
|
-
showChatActions: this.#shouldShowChatActions(),
|
|
904
|
-
showActiveConversationActions: Boolean(this.#conversation && !this.#conversation.isEmpty),
|
|
905
|
-
isTextInputDisabled: this.#isTextInputDisabled(),
|
|
906
|
-
emptyStateSuggestions,
|
|
907
|
-
inputPlaceholder: this.#getChatInputPlaceholder(),
|
|
908
|
-
disclaimerText: this.#getDisclaimerText(),
|
|
909
|
-
isTextInputEmpty: this.#isTextInputEmpty,
|
|
910
|
-
changeManager: this.#changeManager,
|
|
911
|
-
uploadImageInputEnabled: isAiAssistanceMultimodalUploadInputEnabled() &&
|
|
912
|
-
this.#conversation?.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
913
|
-
markdownRenderer,
|
|
914
|
-
onNewChatClick: this.#handleNewChatRequest.bind(this),
|
|
915
|
-
populateHistoryMenu: this.#populateHistoryMenu.bind(this),
|
|
916
|
-
onDeleteClick: this.#onDeleteClicked.bind(this),
|
|
917
|
-
onExportConversationClick: this.#onExportConversationClick.bind(this),
|
|
918
|
-
onHelpClick: () => {
|
|
919
|
-
UI.UIUtils.openInNewTab(AI_ASSISTANCE_HELP);
|
|
920
|
-
},
|
|
921
|
-
onSettingsClick: () => {
|
|
922
|
-
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
923
|
-
},
|
|
924
|
-
onTextSubmit: async (
|
|
925
|
-
text: string, imageInput?: Host.AidaClient.Part,
|
|
926
|
-
multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
|
|
927
|
-
this.#imageInput = undefined;
|
|
928
|
-
this.#isTextInputEmpty = true;
|
|
929
|
-
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
|
|
930
|
-
await this.#startConversation(text, imageInput, multimodalInputType);
|
|
931
|
-
},
|
|
932
|
-
onInspectElementClick: this.#handleSelectElementClick.bind(this),
|
|
933
|
-
onFeedbackSubmit: this.#handleFeedbackSubmit.bind(this),
|
|
934
|
-
onCancelClick: this.#cancel.bind(this),
|
|
935
|
-
onContextClick: this.#handleContextClick.bind(this),
|
|
936
|
-
onNewConversation: this.#handleNewChatRequest.bind(this),
|
|
937
|
-
onTakeScreenshot: isAiAssistanceMultimodalInputEnabled() ? this.#handleTakeScreenshot.bind(this) : undefined,
|
|
938
|
-
onRemoveImageInput: isAiAssistanceMultimodalInputEnabled() ? this.#handleRemoveImageInput.bind(this) :
|
|
939
|
-
undefined,
|
|
940
|
-
onCopyResponseClick: this.#onCopyResponseClick.bind(this),
|
|
941
|
-
onTextInputChange: this.#handleTextInputChange.bind(this),
|
|
942
|
-
onLoadImage: isAiAssistanceMultimodalUploadInputEnabled() ? this.#handleLoadImage.bind(this) : undefined,
|
|
971
|
+
...this.#getToolbarInput(),
|
|
972
|
+
...await this.#getPanelViewInput(),
|
|
943
973
|
},
|
|
944
974
|
this.#viewOutput, this.contentElement);
|
|
945
975
|
}
|
|
@@ -961,20 +991,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
961
991
|
}
|
|
962
992
|
|
|
963
993
|
#isTextInputDisabled(): boolean {
|
|
964
|
-
// If the `aiAssistanceSetting` is not enabled
|
|
965
|
-
// or if the user is blocked by age, the text input is disabled.
|
|
966
|
-
const aiAssistanceSetting = this.#aiAssistanceEnabledSetting?.getIfNotDisabled();
|
|
967
|
-
const isBlockedByAge = Root.Runtime.hostConfig.aidaAvailability?.blockedByAge === true;
|
|
968
|
-
if (!aiAssistanceSetting || isBlockedByAge) {
|
|
969
|
-
return true;
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
// If the Aida is not available, the text input is disabled.
|
|
973
|
-
const isAidaAvailable = this.#aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE;
|
|
974
|
-
if (!isAidaAvailable) {
|
|
975
|
-
return true;
|
|
976
|
-
}
|
|
977
|
-
|
|
978
994
|
// If sending a new message is blocked by cross origin context
|
|
979
995
|
// the text input is disabled.
|
|
980
996
|
if (this.#blockedByCrossOrigin) {
|
|
@@ -1004,8 +1020,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1004
1020
|
}
|
|
1005
1021
|
|
|
1006
1022
|
#getChatInputPlaceholder(): Platform.UIString.LocalizedString {
|
|
1007
|
-
|
|
1008
|
-
if (state === ViewState.DISABLED_VIEW || !this.#conversation) {
|
|
1023
|
+
if (!this.#conversation) {
|
|
1009
1024
|
return i18nString(UIStrings.followTheSteps);
|
|
1010
1025
|
}
|
|
1011
1026
|
|
|
@@ -1037,8 +1052,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1037
1052
|
}
|
|
1038
1053
|
|
|
1039
1054
|
#getDisclaimerText(): Platform.UIString.LocalizedString {
|
|
1040
|
-
|
|
1041
|
-
if (state === ViewState.DISABLED_VIEW || !this.#conversation || this.#conversation.isReadOnly) {
|
|
1055
|
+
if (!this.#conversation || this.#conversation.isReadOnly) {
|
|
1042
1056
|
return i18nString(UIStrings.inputDisclaimerForEmptyState);
|
|
1043
1057
|
}
|
|
1044
1058
|
|
|
@@ -236,13 +236,12 @@ export interface Props {
|
|
|
236
236
|
onLoadImage?: (file: File) => Promise<void>;
|
|
237
237
|
changeManager: AiAssistanceModel.ChangeManager.ChangeManager;
|
|
238
238
|
inspectElementToggled: boolean;
|
|
239
|
-
aidaAvailability: Host.AidaClient.AidaAccessPreconditions;
|
|
240
239
|
messages: ChatMessage[];
|
|
241
240
|
selectedContext: AiAssistanceModel.AiAgent.ConversationContext<unknown>|null;
|
|
242
241
|
isLoading: boolean;
|
|
243
242
|
canShowFeedbackForm: boolean;
|
|
244
243
|
userInfo: Pick<Host.InspectorFrontendHostAPI.SyncInformation, 'accountImage'|'accountFullName'>;
|
|
245
|
-
conversationType
|
|
244
|
+
conversationType: AiAssistanceModel.AiHistoryStorage.ConversationType;
|
|
246
245
|
isReadOnly: boolean;
|
|
247
246
|
blockedByCrossOrigin: boolean;
|
|
248
247
|
changeSummary?: string;
|
|
@@ -469,7 +468,6 @@ export class ChatView extends HTMLElement {
|
|
|
469
468
|
const renderFooter = (): Lit.LitTemplate => {
|
|
470
469
|
const classes = Lit.Directives.classMap({
|
|
471
470
|
'chat-view-footer': true,
|
|
472
|
-
'has-conversation': !!this.#props.conversationType,
|
|
473
471
|
'is-read-only': this.#props.isReadOnly,
|
|
474
472
|
});
|
|
475
473
|
|
|
@@ -488,9 +486,8 @@ export class ChatView extends HTMLElement {
|
|
|
488
486
|
};
|
|
489
487
|
|
|
490
488
|
const renderInputOrReadOnlySection = (): Lit.LitTemplate => {
|
|
491
|
-
if (this.#props.
|
|
489
|
+
if (this.#props.isReadOnly) {
|
|
492
490
|
return renderReadOnlySection({
|
|
493
|
-
conversationType: this.#props.conversationType,
|
|
494
491
|
onNewConversation: this.#props.onNewConversation,
|
|
495
492
|
});
|
|
496
493
|
}
|
|
@@ -506,7 +503,6 @@ export class ChatView extends HTMLElement {
|
|
|
506
503
|
multimodalInputEnabled: this.#props.multimodalInputEnabled,
|
|
507
504
|
conversationType: this.#props.conversationType,
|
|
508
505
|
imageInput: this.#props.imageInput,
|
|
509
|
-
aidaAvailability: this.#props.aidaAvailability,
|
|
510
506
|
isTextInputEmpty: this.#props.isTextInputEmpty,
|
|
511
507
|
uploadImageInputEnabled: this.#props.uploadImageInputEnabled,
|
|
512
508
|
onContextClick: this.#props.onContextClick,
|
|
@@ -957,12 +953,8 @@ function renderSelection({
|
|
|
957
953
|
isTextInputDisabled: boolean,
|
|
958
954
|
onContextClick: () => void | Promise<void>,
|
|
959
955
|
onInspectElementClick: () => void,
|
|
960
|
-
conversationType
|
|
956
|
+
conversationType: AiAssistanceModel.AiHistoryStorage.ConversationType,
|
|
961
957
|
}): Lit.LitTemplate {
|
|
962
|
-
if (!conversationType) {
|
|
963
|
-
return Lit.nothing;
|
|
964
|
-
}
|
|
965
|
-
|
|
966
958
|
// TODO: currently the picker behavior is SDKNode specific.
|
|
967
959
|
const hasPickerBehavior = conversationType === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING;
|
|
968
960
|
|
|
@@ -1119,14 +1111,9 @@ function renderEmptyState({isTextInputDisabled, suggestions, onSuggestionClick}:
|
|
|
1119
1111
|
// clang-format on
|
|
1120
1112
|
}
|
|
1121
1113
|
|
|
1122
|
-
function renderReadOnlySection({onNewConversation
|
|
1114
|
+
function renderReadOnlySection({onNewConversation}: {
|
|
1123
1115
|
onNewConversation: () => void,
|
|
1124
|
-
conversationType?: AiAssistanceModel.AiHistoryStorage.ConversationType,
|
|
1125
1116
|
}): Lit.LitTemplate {
|
|
1126
|
-
if (!conversationType) {
|
|
1127
|
-
return Lit.nothing;
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
1117
|
// clang-format off
|
|
1131
1118
|
return html`<div
|
|
1132
1119
|
class="chat-readonly-container"
|
|
@@ -1355,7 +1342,6 @@ function renderChatInput({
|
|
|
1355
1342
|
imageInput,
|
|
1356
1343
|
isTextInputEmpty,
|
|
1357
1344
|
uploadImageInputEnabled,
|
|
1358
|
-
aidaAvailability,
|
|
1359
1345
|
disclaimerText,
|
|
1360
1346
|
onContextClick,
|
|
1361
1347
|
onInspectElementClick,
|
|
@@ -1375,7 +1361,6 @@ function renderChatInput({
|
|
|
1375
1361
|
selectedContext: AiAssistanceModel.AiAgent.ConversationContext<unknown>|null,
|
|
1376
1362
|
inspectElementToggled: boolean,
|
|
1377
1363
|
isTextInputEmpty: boolean,
|
|
1378
|
-
aidaAvailability: Host.AidaClient.AidaAccessPreconditions,
|
|
1379
1364
|
disclaimerText: string,
|
|
1380
1365
|
onContextClick: () => void,
|
|
1381
1366
|
onInspectElementClick: () => void,
|
|
@@ -1384,19 +1369,15 @@ function renderChatInput({
|
|
|
1384
1369
|
onCancel: (ev: SubmitEvent) => void,
|
|
1385
1370
|
onNewConversation: () => void,
|
|
1386
1371
|
onTextInputChange: (input: string) => void,
|
|
1372
|
+
conversationType: AiAssistanceModel.AiHistoryStorage.ConversationType,
|
|
1387
1373
|
multimodalInputEnabled?: boolean,
|
|
1388
|
-
conversationType?: AiAssistanceModel.AiHistoryStorage.ConversationType,
|
|
1389
1374
|
imageInput?: ImageInputData,
|
|
1390
1375
|
uploadImageInputEnabled?: boolean,
|
|
1391
1376
|
onTakeScreenshot?: () => void,
|
|
1392
1377
|
onRemoveImageInput?: () => void,
|
|
1393
1378
|
onImageUpload?: (ev: Event) => void,
|
|
1394
1379
|
}): Lit.LitTemplate {
|
|
1395
|
-
|
|
1396
|
-
return Lit.nothing;
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
const shouldShowMultiLine = aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE && selectedContext;
|
|
1380
|
+
const shouldShowMultiLine = selectedContext;
|
|
1400
1381
|
const chatInputContainerCls = Lit.Directives.classMap({
|
|
1401
1382
|
'chat-input-container': true,
|
|
1402
1383
|
'single-line-layout': !shouldShowMultiLine,
|
|
@@ -1457,7 +1438,6 @@ function renderMainContents({
|
|
|
1457
1438
|
suggestions,
|
|
1458
1439
|
userInfo,
|
|
1459
1440
|
markdownRenderer,
|
|
1460
|
-
conversationType,
|
|
1461
1441
|
changeSummary,
|
|
1462
1442
|
changeManager,
|
|
1463
1443
|
onSuggestionClick,
|
|
@@ -1478,13 +1458,9 @@ function renderMainContents({
|
|
|
1478
1458
|
onFeedbackSubmit: (rpcId: Host.AidaClient.RpcGlobalId, rate: Host.AidaClient.Rating, feedback?: string) => void,
|
|
1479
1459
|
onCopyResponseClick: (message: ModelChatMessage) => void,
|
|
1480
1460
|
onMessageContainerRef: (el: Element|undefined) => void,
|
|
1481
|
-
conversationType
|
|
1461
|
+
conversationType: AiAssistanceModel.AiHistoryStorage.ConversationType,
|
|
1482
1462
|
changeSummary?: string,
|
|
1483
1463
|
}): Lit.LitTemplate {
|
|
1484
|
-
if (!conversationType) {
|
|
1485
|
-
return Lit.nothing;
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
1464
|
if (messages.length > 0) {
|
|
1489
1465
|
return renderMessages({
|
|
1490
1466
|
messages,
|
|
@@ -294,7 +294,7 @@ footer.chat-view-footer {
|
|
|
294
294
|
The footer (for active conversations) is hidden by default on wider screens
|
|
295
295
|
because the disclaimer is shown inline within the chat input actions. Show it only on narrow widths (< 400px).
|
|
296
296
|
*/
|
|
297
|
-
|
|
297
|
+
&:not(.is-read-only) {
|
|
298
298
|
display: none;
|
|
299
299
|
border: none;
|
|
300
300
|
|
|
@@ -147,6 +147,7 @@ const UIStrings = {
|
|
|
147
147
|
|
|
148
148
|
const str_ = i18n.i18n.registerUIStrings('panels/application/components/BackForwardCacheView.ts', UIStrings);
|
|
149
149
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
150
|
+
const {widgetConfig} = UI.Widget;
|
|
150
151
|
|
|
151
152
|
const enum ScreenStatusType {
|
|
152
153
|
RUNNING = 'Running',
|
|
@@ -384,16 +385,18 @@ function maybeRenderJavaScriptDetails(details: Protocol.Page.BackForwardCacheBlo
|
|
|
384
385
|
return nothing;
|
|
385
386
|
}
|
|
386
387
|
const maxLengthForDisplayedURLs = 50;
|
|
387
|
-
const linkifier = new Components.Linkifier.Linkifier(maxLengthForDisplayedURLs);
|
|
388
388
|
const rows = [html`<div>${i18nString(UIStrings.filesPerIssue, {n: details.length})}</div>`];
|
|
389
|
-
rows.push(...details.map(
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
389
|
+
rows.push(...details.map(detail => html`
|
|
390
|
+
<devtools-widget .widgetConfig=${widgetConfig(Components.Linkifier.ScriptLocationLink, {
|
|
391
|
+
sourceURL: detail.url as Platform.DevToolsPath.UrlString,
|
|
392
|
+
lineNumber: detail.lineNumber,
|
|
393
|
+
options: {
|
|
394
|
+
columnNumber: detail.columnNumber,
|
|
395
|
+
showColumnNumber: true,
|
|
396
|
+
inlineFrameIndex: 0,
|
|
397
|
+
maxLength: maxLengthForDisplayedURLs,
|
|
398
|
+
}
|
|
399
|
+
})}></devtools-widget>`));
|
|
397
400
|
return html`
|
|
398
401
|
<div class="details-list">
|
|
399
402
|
<devtools-expandable-list .data=${
|
|
@@ -357,11 +357,16 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
357
357
|
this.#timeoutId = setTimeout(this.#setSlow.bind(this), SLOW_GENERATION_CUTOFF_MILLISECONDS);
|
|
358
358
|
const startTime = performance.now();
|
|
359
359
|
let teaserText = '';
|
|
360
|
+
let firstChunkReceived = false;
|
|
360
361
|
try {
|
|
361
362
|
for await (const chunk of this.#getOnDeviceInsight()) {
|
|
362
363
|
teaserText += chunk;
|
|
363
364
|
this.#mainText = teaserText;
|
|
364
365
|
this.requestUpdate();
|
|
366
|
+
if (!firstChunkReceived) {
|
|
367
|
+
firstChunkReceived = true;
|
|
368
|
+
Host.userMetrics.consoleInsightTeaserFirstChunkGenerated(performance.now() - startTime);
|
|
369
|
+
}
|
|
365
370
|
}
|
|
366
371
|
} catch (err) {
|
|
367
372
|
// Ignore `AbortError` errors, which are thrown on mouse leave.
|
|
@@ -75,7 +75,7 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
|
|
|
75
75
|
private aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
|
|
76
76
|
private boundOnAidaAvailabilityChange?: () => Promise<void>;
|
|
77
77
|
private aiCodeCompletion?: AiCodeCompletion.AiCodeCompletion.AiCodeCompletion;
|
|
78
|
-
|
|
78
|
+
teaser?: PanelCommon.AiCodeCompletionTeaser;
|
|
79
79
|
private placeholderCompartment: CodeMirror.Compartment = new CodeMirror.Compartment();
|
|
80
80
|
private aiCodeCompletionSetting =
|
|
81
81
|
Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
|
|
@@ -554,7 +554,14 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
|
|
|
554
554
|
this.teaser = undefined;
|
|
555
555
|
}
|
|
556
556
|
this.aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion.AiCodeCompletion(
|
|
557
|
-
{aidaClient: this.aidaClient},
|
|
557
|
+
{aidaClient: this.aidaClient}, AiCodeCompletion.AiCodeCompletion.ContextFlavor.CONSOLE, {
|
|
558
|
+
getSelectionHead: () => this.editor.editor.state.selection.main.head,
|
|
559
|
+
getCompletionHint: () => this.editor.editor.plugin(TextEditor.Config.showCompletionHint)?.currentHint,
|
|
560
|
+
setAiAutoCompletion: (suggestion: TextEditor.Config.ActiveSuggestion|null) => {
|
|
561
|
+
this.editor.dispatch({effects: TextEditor.Config.setAiAutoCompleteSuggestion.of(suggestion)});
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
['\n\n']);
|
|
558
565
|
this.aiCodeCompletion.addEventListener(AiCodeCompletion.AiCodeCompletion.Events.RESPONSE_RECEIVED, event => {
|
|
559
566
|
this.aiCodeCompletionCitations = event.data.citations;
|
|
560
567
|
this.dispatchEventToListeners(Events.AI_CODE_COMPLETION_RESPONSE_RECEIVED, event.data);
|
|
@@ -1457,6 +1457,9 @@ export class ConsoleView extends UI.Widget.VBox implements
|
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
1459
|
private async keyDown(event: Event): Promise<void> {
|
|
1460
|
+
if (!this.prompt.teaser?.isShowing()) {
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1460
1463
|
const keyboardEvent = (event as KeyboardEvent);
|
|
1461
1464
|
if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(keyboardEvent)) {
|
|
1462
1465
|
if (keyboardEvent.key === 'i') {
|
|
@@ -325,7 +325,6 @@ const UIStrings = {
|
|
|
325
325
|
/**
|
|
326
326
|
* @description Tooltip to explain why the request has an IPP icon
|
|
327
327
|
*/
|
|
328
|
-
responseIsIpProtectedToolTip: 'This request was sent through IP Protection proxies.',
|
|
329
328
|
} as const;
|
|
330
329
|
const str_ = i18n.i18n.registerUIStrings('panels/network/NetworkDataGridNode.ts', UIStrings);
|
|
331
330
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -1175,12 +1174,6 @@ export class NetworkRequestNode extends NetworkNode {
|
|
|
1175
1174
|
cell.addEventListener('focus', () => this.parentView().resetFocus());
|
|
1176
1175
|
|
|
1177
1176
|
// render icons
|
|
1178
|
-
if (this.requestInternal.isIpProtectionUsed()) {
|
|
1179
|
-
const ippIcon = IconButton.Icon.create('shield', 'icon');
|
|
1180
|
-
ippIcon.title = i18nString(UIStrings.responseIsIpProtectedToolTip);
|
|
1181
|
-
ippIcon.style.color = 'var(--sys-color-on-surface-subtle);';
|
|
1182
|
-
cell.appendChild(ippIcon);
|
|
1183
|
-
}
|
|
1184
1177
|
|
|
1185
1178
|
const iconElement = PanelUtils.getIconForNetworkRequest(this.requestInternal);
|
|
1186
1179
|
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|