Skip to content

Commit b18e7a7

Browse files
authored
chat setup & quota tweaks (microsoft#235550)
* chat - assorted fixes (microsoft#235539) * Copilot setup fails to focus chat input after setup (microsoft/vscode-copilot#11154) * chat - removal of checkboxes * chat - unbreak 🤖 icon from appearing * chat - tweak wording * chat - setup/quota tweaks (microsoft#235543)
1 parent e8e69d3 commit b18e7a7

File tree

4 files changed

+33
-92
lines changed

4 files changed

+33
-92
lines changed

src/vs/workbench/contrib/chat/browser/actions/chatActions.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandCenter, {
534534
when: ContextKeyExpr.and(
535535
ContextKeyExpr.has('config.chat.commandCenter.enabled'),
536536
ContextKeyExpr.or(
537-
ContextKeyExpr.and(
538-
ContextKeyExpr.has('config.chat.experimental.offerSetup'),
539-
ChatContextKeys.Setup.entitled,
540-
),
537+
ContextKeyExpr.has('config.chat.experimental.offerSetup'),
541538
ChatContextKeys.Setup.installed,
542539
ChatContextKeys.panelParticipantRegistered
543540
)
@@ -555,7 +552,6 @@ registerAction2(class ToggleCopilotControl extends ToggleTitleBarConfigAction {
555552
ContextKeyExpr.has('config.window.commandCenter'),
556553
ContextKeyExpr.or(
557554
ChatContextKeys.Setup.installed,
558-
ChatContextKeys.Setup.entitled,
559555
ContextKeyExpr.has('config.chat.experimental.offerSetup'),
560556
ChatContextKeys.panelParticipantRegistered
561557
)

src/vs/workbench/contrib/chat/browser/chatSetup.ts

Lines changed: 30 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import './media/chatViewSetup.css';
7-
import { $, addDisposableListener, EventType, getActiveElement, setVisibility } from '../../../../base/browser/dom.js';
7+
import { $, getActiveElement, setVisibility } from '../../../../base/browser/dom.js';
88
import { Button, ButtonWithDropdown } from '../../../../base/browser/ui/button/button.js';
99
import { renderIcon } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
1010
import { IAction, toAction } from '../../../../base/common/actions.js';
@@ -37,7 +37,7 @@ import { Registry } from '../../../../platform/registry/common/platform.js';
3737
import { asText, IRequestService } from '../../../../platform/request/common/request.js';
3838
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
3939
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
40-
import { defaultButtonStyles, defaultCheckboxStyles } from '../../../../platform/theme/browser/defaultStyles.js';
40+
import { defaultButtonStyles } from '../../../../platform/theme/browser/defaultStyles.js';
4141
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
4242
import { IWorkbenchContribution } from '../../../common/contributions.js';
4343
import { IViewDescriptorService, ViewContainerLocation } from '../../../common/views.js';
@@ -55,7 +55,6 @@ import { ChatViewId, EditsViewId, ensureSideBarChatViewSize, IChatWidget, showCh
5555
import { CHAT_EDITING_SIDEBAR_PANEL_ID, CHAT_SIDEBAR_PANEL_ID } from './chatViewPane.js';
5656
import { ChatViewsWelcomeExtensions, IChatViewsWelcomeContributionRegistry } from './viewsWelcome/chatViewsWelcome.js';
5757
import { IChatQuotasService } from './chatQuotasService.js';
58-
import { Checkbox } from '../../../../base/browser/ui/toggle/toggle.js';
5958
import { mainWindow } from '../../../../base/browser/window.js';
6059

6160
const defaultChat = {
@@ -65,7 +64,6 @@ const defaultChat = {
6564
termsStatementUrl: product.defaultChatAgent?.termsStatementUrl ?? '',
6665
privacyStatementUrl: product.defaultChatAgent?.privacyStatementUrl ?? '',
6766
skusDocumentationUrl: product.defaultChatAgent?.skusDocumentationUrl ?? '',
68-
publicCodeMatchesUrl: product.defaultChatAgent?.publicCodeMatchesUrl ?? '',
6967
providerId: product.defaultChatAgent?.providerId ?? '',
7068
providerName: product.defaultChatAgent?.providerName ?? '',
7169
providerScopes: product.defaultChatAgent?.providerScopes ?? [[]],
@@ -88,8 +86,6 @@ enum ChatEntitlement {
8886
Pro
8987
}
9088

91-
const ASK_FOR_PUBLIC_CODE_MATCHES = false; // TODO@bpasero revisit this
92-
9389
//#region Contribution
9490

9591
const TRIGGER_SETUP_COMMAND_ID = 'workbench.action.chat.triggerSetup';
@@ -158,10 +154,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
158154
f1: true,
159155
precondition: ContextKeyExpr.and(
160156
ChatContextKeys.Setup.installed.negate(),
161-
ContextKeyExpr.or(
162-
ChatContextKeys.Setup.entitled,
163-
ContextKeyExpr.has('config.chat.experimental.offerSetup')
164-
)
157+
ContextKeyExpr.has('config.chat.experimental.offerSetup')
165158
),
166159
menu: {
167160
id: MenuId.ChatCommandCenter,
@@ -183,9 +176,9 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
183176
showCopilotView(viewsService, layoutService);
184177
ensureSideBarChatViewSize(400, viewDescriptorService, layoutService);
185178

186-
if (startSetup === true && !ASK_FOR_PUBLIC_CODE_MATCHES) {
179+
if (startSetup === true) {
187180
const controller = that.controller.value;
188-
controller.setup({ publicCodeSuggestions: true });
181+
controller.setup();
189182
}
190183

191184
configurationService.updateValue('chat.commandCenter.enabled', true);
@@ -205,10 +198,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
205198
category: CHAT_CATEGORY,
206199
precondition: ContextKeyExpr.and(
207200
ChatContextKeys.Setup.installed.negate(),
208-
ContextKeyExpr.or(
209-
ChatContextKeys.Setup.entitled,
210-
ContextKeyExpr.has('config.chat.experimental.offerSetup')
211-
)
201+
ContextKeyExpr.has('config.chat.experimental.offerSetup')
212202
),
213203
menu: {
214204
id: MenuId.ChatCommandCenter,
@@ -521,10 +511,10 @@ class ChatSetupRequests extends Disposable {
521511
return this.resolveEntitlement(session, CancellationToken.None);
522512
}
523513

524-
async signUpLimited(session: AuthenticationSession, options: { publicCodeSuggestions: boolean }): Promise<boolean> {
514+
async signUpLimited(session: AuthenticationSession): Promise<boolean> {
525515
const body = {
526516
restricted_telemetry: 'disabled',
527-
public_code_suggestions: options.publicCodeSuggestions ? 'enabled' : 'disabled'
517+
public_code_suggestions: 'enabled'
528518
};
529519

530520
const response = await this.request(defaultChat.entitlementSignupLimitedUrl, 'POST', body, session, CancellationToken.None);
@@ -637,7 +627,7 @@ class ChatSetupController extends Disposable {
637627
this._onDidChange.fire();
638628
}
639629

640-
async setup(options: { publicCodeSuggestions: boolean }): Promise<void> {
630+
async setup(): Promise<void> {
641631
const title = localize('setupChatProgress', "Getting Copilot ready...");
642632
const badge = this.activityService.showViewContainerActivity(isCopilotEditsViewActive(this.viewsService) ? CHAT_EDITING_SIDEBAR_PANEL_ID : CHAT_SIDEBAR_PANEL_ID, {
643633
badge: new ProgressBadge(() => title),
@@ -649,14 +639,16 @@ class ChatSetupController extends Disposable {
649639
location: ProgressLocation.Window,
650640
command: TRIGGER_SETUP_COMMAND_ID,
651641
title,
652-
}, () => this.doSetup(options));
642+
}, () => this.doSetup());
653643
} finally {
654644
badge.dispose();
655645
}
656646
}
657647

658-
private async doSetup(options: { publicCodeSuggestions: boolean }): Promise<void> {
648+
private async doSetup(): Promise<void> {
659649
this.context.suspend(); // reduces flicker
650+
651+
let focusChatInput = false;
660652
try {
661653
let session: AuthenticationSession | undefined;
662654
let entitlement: ChatEntitlement | undefined;
@@ -680,20 +672,30 @@ class ChatSetupController extends Disposable {
680672
}
681673
}
682674

675+
const activeElement = getActiveElement();
676+
683677
// Install
684678
this.setStep(ChatSetupStep.Installing);
685-
await this.install(session, entitlement ?? this.context.state.entitlement, options);
679+
await this.install(session, entitlement ?? this.context.state.entitlement);
680+
681+
const currentActiveElement = getActiveElement();
682+
focusChatInput = activeElement === currentActiveElement || currentActiveElement === mainWindow.document.body;
686683
} finally {
687684
this.setStep(ChatSetupStep.Initial);
688685
this.context.resume();
689686
}
687+
688+
if (focusChatInput) {
689+
(await showCopilotView(this.viewsService, this.layoutService))?.focusInput();
690+
}
690691
}
691692

692693
private async signIn(): Promise<{ session: AuthenticationSession | undefined; entitlement: ChatEntitlement | undefined }> {
693694
let session: AuthenticationSession | undefined;
694695
let entitlement: ChatEntitlement | undefined;
695696
try {
696697
showCopilotView(this.viewsService, this.layoutService);
698+
697699
session = await this.authenticationService.createSession(defaultChat.providerId, defaultChat.providerScopes[0]);
698700
entitlement = await this.requests.forceResolveEntitlement(session);
699701
} catch (error) {
@@ -707,9 +709,8 @@ class ChatSetupController extends Disposable {
707709
return { session, entitlement };
708710
}
709711

710-
private async install(session: AuthenticationSession, entitlement: ChatEntitlement, options: { publicCodeSuggestions: boolean }): Promise<void> {
712+
private async install(session: AuthenticationSession, entitlement: ChatEntitlement,): Promise<void> {
711713
const signedIn = !!session;
712-
const activeElement = getActiveElement();
713714

714715
let installResult: 'installed' | 'cancelled' | 'failedInstall' | undefined = undefined;
715716
const wasInstalled = this.context.state.installed;
@@ -718,7 +719,7 @@ class ChatSetupController extends Disposable {
718719
showCopilotView(this.viewsService, this.layoutService);
719720

720721
if (entitlement !== ChatEntitlement.Limited && entitlement !== ChatEntitlement.Pro && entitlement !== ChatEntitlement.Unavailable) {
721-
didSignUp = await this.requests.signUpLimited(session, options);
722+
didSignUp = await this.requests.signUpLimited(session);
722723
}
723724

724725
await this.extensionsWorkbenchService.install(defaultChat.extensionId, {
@@ -747,11 +748,6 @@ class ChatSetupController extends Disposable {
747748
}
748749

749750
this.telemetryService.publicLog2<InstallChatEvent, InstallChatClassification>('commandCenter.chatInstall', { installResult, signedIn });
750-
751-
const currentActiveElement = getActiveElement();
752-
if (activeElement === currentActiveElement || currentActiveElement === mainWindow.document.body) {
753-
(await showCopilotView(this.viewsService, this.layoutService))?.focusInput();
754-
}
755751
}
756752
}
757753

@@ -802,18 +798,14 @@ class ChatSetupWelcomeContent extends Disposable {
802798
}
803799

804800
// Limited SKU
805-
const limitedSkuHeader = localize({ key: 'limitedSkuHeader', comment: ['{Locked="[]({0})"}'] }, "$(sparkle-filled) We now offer [Copilot for free]({0}).", defaultChat.skusDocumentationUrl);
801+
const limitedSkuHeader = localize({ key: 'limitedSkuHeader', comment: ['{Locked="[]({0})"}'] }, "$(sparkle-filled) We now offer [Copilot for free]({0}) with 50 chat messages and 2000 code completions per month.", defaultChat.skusDocumentationUrl);
806802
const limitedSkuHeaderContainer = this.element.appendChild($('p'));
807803
limitedSkuHeaderContainer.appendChild(this._register(markdown.render(new MarkdownString(limitedSkuHeader, { isTrusted: true, supportThemeIcons: true }))).element);
808804

809-
const publicCodeSuggestionsLabel = localize('detectionLabel', "Allow code suggestions that [match public code]({0})", defaultChat.publicCodeMatchesUrl);
810-
const { container: publicCodeSuggestionsContainer, checkbox: publicCodeSuggestionsCheckbox } = this.createCheckBox(publicCodeSuggestionsLabel, true, markdown);
811-
812805
// Terms
813806
const terms = localize({ key: 'termsLabel', comment: ['{Locked="["}', '{Locked="]({0})"}', '{Locked="]({1})"}'] }, "By continuing, you agree to our [Terms]({0}) and [Privacy Policy]({1}).", defaultChat.termsStatementUrl, defaultChat.privacyStatementUrl);
814807
const termsContainer = this.element.appendChild($('p'));
815808
termsContainer.classList.add('terms-container');
816-
termsContainer.classList.toggle('is-standalone', !ASK_FOR_PUBLIC_CODE_MATCHES);
817809
termsContainer.appendChild(this._register(markdown.render(new MarkdownString(terms, { isTrusted: true }))).element);
818810

819811
// Setup Button
@@ -833,30 +825,13 @@ class ChatSetupWelcomeContent extends Disposable {
833825
supportIcons: true,
834826
...defaultButtonStyles
835827
}));
836-
this._register(button.onDidClick(() => this.controller.setup({ publicCodeSuggestions: ASK_FOR_PUBLIC_CODE_MATCHES ? publicCodeSuggestionsCheckbox.checked : true })));
828+
this._register(button.onDidClick(() => this.controller.setup()));
837829

838830
// Update based on model state
839-
this._register(Event.runAndSubscribe(this.controller.onDidChange, () => this.update(limitedSkuHeaderContainer, button, [publicCodeSuggestionsContainer], [publicCodeSuggestionsCheckbox])));
831+
this._register(Event.runAndSubscribe(this.controller.onDidChange, () => this.update(limitedSkuHeaderContainer, button)));
840832
}
841833

842-
private createCheckBox(label: string, checked: boolean, markdown: MarkdownRenderer): { container: HTMLElement; checkbox: Checkbox } {
843-
const container = this.element.appendChild($('p.checkbox-container'));
844-
const checkbox = this._register(new Checkbox(label, checked, defaultCheckboxStyles));
845-
container.appendChild(checkbox.domNode);
846-
847-
const checkboxLabel = container.appendChild(this._register(markdown.render(new MarkdownString(label, { isTrusted: true, supportThemeIcons: true }), { inline: true, className: 'checkbox-label' })).element);
848-
this._register(addDisposableListener(checkboxLabel, EventType.CLICK, e => {
849-
if (checkbox?.enabled && (e.target as HTMLElement).tagName !== 'A') {
850-
checkbox.checked = !checkbox.checked;
851-
checkbox.focus();
852-
}
853-
}));
854-
855-
return { container, checkbox };
856-
}
857-
858-
private update(limitedSkuHeaderContainer: HTMLElement, button: Button | ButtonWithDropdown, limitedCheckboxContainers: HTMLElement[], limitedCheckboxes: Checkbox[]): void {
859-
const showLimitedCheckboxes = ASK_FOR_PUBLIC_CODE_MATCHES ? this.context.state.entitlement !== ChatEntitlement.Limited && this.context.state.entitlement !== ChatEntitlement.Pro && this.context.state.entitlement !== ChatEntitlement.Unavailable : false;
834+
private update(limitedSkuHeaderContainer: HTMLElement, button: Button | ButtonWithDropdown): void {
860835
let showLimitedSkuHeader: boolean;
861836
let buttonLabel: string;
862837

@@ -882,27 +857,15 @@ class ChatSetupWelcomeContent extends Disposable {
882857
}
883858

884859
switch (this.controller.step) {
885-
case ChatSetupStep.Initial:
886-
for (const checkbox of limitedCheckboxes) {
887-
checkbox.enable();
888-
}
889-
break;
890860
case ChatSetupStep.SigningIn:
891-
for (const checkbox of limitedCheckboxes) {
892-
checkbox.disable();
893-
}
894861
buttonLabel = localize('setupChatSignIn', "$(loading~spin) Signing in to {0}...", defaultChat.providerName);
895862
break;
896863
case ChatSetupStep.Installing:
897-
for (const checkbox of limitedCheckboxes) {
898-
checkbox.disable();
899-
}
900864
buttonLabel = localize('setupChatInstalling', "$(loading~spin) Getting Copilot Ready...");
901865
break;
902866
}
903867

904868
setVisibility(showLimitedSkuHeader, limitedSkuHeaderContainer);
905-
setVisibility(showLimitedCheckboxes, ...limitedCheckboxContainers);
906869

907870
button.label = buttonLabel;
908871
button.enabled = this.controller.step === ChatSetupStep.Initial;
@@ -926,7 +889,6 @@ class ChatSetupContext extends Disposable {
926889

927890
private readonly canSignUpContextKey = ChatContextKeys.Setup.canSignUp.bindTo(this.contextKeyService);
928891
private readonly signedOutContextKey = ChatContextKeys.Setup.signedOut.bindTo(this.contextKeyService);
929-
private readonly entitledContextKey = ChatContextKeys.Setup.entitled.bindTo(this.contextKeyService);
930892
private readonly limitedContextKey = ChatContextKeys.Setup.limited.bindTo(this.contextKeyService);
931893
private readonly triggeredContext = ChatContextKeys.Setup.triggered.bindTo(this.contextKeyService);
932894
private readonly installedContext = ChatContextKeys.Setup.installed.bindTo(this.contextKeyService);
@@ -1031,7 +993,6 @@ class ChatSetupContext extends Disposable {
1031993
changed = this.updateContextKey(this.signedOutContextKey, this._state.entitlement === ChatEntitlement.Unknown) || changed;
1032994
changed = this.updateContextKey(this.canSignUpContextKey, this._state.entitlement === ChatEntitlement.Available) || changed;
1033995
changed = this.updateContextKey(this.limitedContextKey, this._state.entitlement === ChatEntitlement.Limited) || changed;
1034-
changed = this.updateContextKey(this.entitledContextKey, this._state.entitlement === ChatEntitlement.Pro) || changed;
1035996
changed = this.updateContextKey(this.triggeredContext, !!this._state.triggered) || changed;
1036997
changed = this.updateContextKey(this.installedContext, !!this._state.installed) || changed;
1037998

src/vs/workbench/contrib/chat/browser/media/chatViewSetup.css

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
background-color: var(--vscode-chat-requestBackground);
1818
}
1919

20-
.terms-container.is-standalone {
20+
.terms-container {
2121
padding-top: 5px;
2222
}
2323

@@ -29,7 +29,7 @@
2929
}
3030

3131
.chat-feature-container .codicon[class*='codicon-'] {
32-
font-size: 20px;
32+
font-size: 16px;
3333
}
3434

3535
.codicon[class*='codicon-'] {
@@ -54,19 +54,4 @@
5454
width: 100%;
5555
padding: 4px 7px;
5656
}
57-
58-
/** Checkboxes */
59-
.checkbox-container {
60-
display: flex;
61-
padding-top: 15px;
62-
}
63-
64-
.checkbox-label {
65-
flex-basis: fit-content;
66-
cursor: pointer;
67-
}
68-
69-
.checkbox-label p {
70-
display: inline;
71-
}
7257
}

src/vs/workbench/contrib/chat/common/chatContextKeys.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export namespace ChatContextKeys {
4545
canSignUp: new RawContextKey<boolean>('chatSetupCanSignUp', false, true), // True when user can sign up to be a chat limited user.
4646

4747
signedOut: new RawContextKey<boolean>('chatSetupSignedOut', false, true), // True when user is signed out.
48-
entitled: new RawContextKey<boolean>('chatSetupEntitled', false, true), // True when user is a chat entitled user.
4948
limited: new RawContextKey<boolean>('chatSetupLimited', false, true), // True when user is a chat limited user.
5049

5150
triggered: new RawContextKey<boolean>('chatSetupTriggered', false, true), // True when chat setup is triggered.

0 commit comments

Comments
 (0)