Skip to content

Commit 116b986

Browse files
authored
chat - status and setup cleanup (#243573)
1 parent 458154a commit 116b986

File tree

5 files changed

+201
-180
lines changed

5 files changed

+201
-180
lines changed

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

+6-7
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { DropdownWithPrimaryActionViewItem } from '../../../../../platform/actio
2424
import { Action2, MenuId, MenuItemAction, MenuRegistry, registerAction2, SubmenuItemAction } from '../../../../../platform/actions/common/actions.js';
2525
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
2626
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
27-
import { ContextKeyExpr, IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';
27+
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
2828
import { IsLinuxContext, IsWindowsContext } from '../../../../../platform/contextkey/common/contextkeys.js';
2929
import { IDialogService } from '../../../../../platform/dialogs/common/dialogs.js';
3030
import { IInstantiationService, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
@@ -43,7 +43,7 @@ import { IViewsService } from '../../../../services/views/common/viewsService.js
4343
import { EXTENSIONS_CATEGORY, IExtensionsWorkbenchService } from '../../../extensions/common/extensions.js';
4444
import { IChatAgentService } from '../../common/chatAgents.js';
4545
import { ChatContextKeys } from '../../common/chatContextKeys.js';
46-
import { ChatEntitlement, IChatEntitlementService } from '../../common/chatEntitlementService.js';
46+
import { ChatEntitlement, ChatSentiment, IChatEntitlementService } from '../../common/chatEntitlementService.js';
4747
import { extractAgentAndCommand } from '../../common/chatParserTypes.js';
4848
import { IChatDetail, IChatService } from '../../common/chatService.js';
4949
import { IChatRequestViewModel, IChatResponseViewModel, isRequestVM } from '../../common/chatViewModel.js';
@@ -514,8 +514,8 @@ export function registerChatActions() {
514514
f1: true,
515515
precondition: ContextKeyExpr.and(
516516
ContextKeyExpr.or(
517-
ChatContextKeys.Setup.limited,
518-
ChatContextKeys.Setup.pro
517+
ChatContextKeys.Entitlement.limited,
518+
ChatContextKeys.Entitlement.pro
519519
),
520520
nonEnterpriseCopilotUsers
521521
),
@@ -692,7 +692,6 @@ export class CopilotTitleBarMenuRendering extends Disposable implements IWorkben
692692
@IChatAgentService agentService: IChatAgentService,
693693
@IInstantiationService instantiationService: IInstantiationService,
694694
@IChatEntitlementService chatEntitlementService: IChatEntitlementService,
695-
@IContextKeyService contextKeyService: IContextKeyService,
696695
@IConfigurationService configurationService: IConfigurationService,
697696
) {
698697
super();
@@ -708,7 +707,7 @@ export class CopilotTitleBarMenuRendering extends Disposable implements IWorkben
708707
run() { }
709708
});
710709

711-
const chatExtensionInstalled = contextKeyService.getContextKeyValue<boolean>(ChatContextKeys.Setup.installed.key) === true;
710+
const chatExtensionInstalled = chatEntitlementService.sentiment === ChatSentiment.Installed;
712711
const { chatQuotaExceeded, completionsQuotaExceeded } = chatEntitlementService.quotas;
713712
const signedOut = chatEntitlementService.entitlement === ChatEntitlement.Unknown;
714713
const setupFromDialog = configurationService.getValue('chat.experimental.setupFromDialog');
@@ -745,7 +744,7 @@ export class CopilotTitleBarMenuRendering extends Disposable implements IWorkben
745744
icon: primaryActionIcon,
746745
}, undefined, undefined, undefined, undefined), dropdownAction, action.actions, '', { ...options, skipTelemetry: true });
747746
}, Event.any(
748-
agentService.onDidChangeAgents,
747+
chatEntitlementService.onDidChangeSentiment,
749748
chatEntitlementService.onDidChangeQuotaExceeded,
750749
chatEntitlementService.onDidChangeEntitlement,
751750
Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('chat.experimental.setupFromDialog'))

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

+30-22
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import './media/chatViewSetup.css';
67
import { $, getActiveElement, setVisibility } from '../../../../base/browser/dom.js';
78
import { ButtonWithDropdown } from '../../../../base/browser/ui/button/button.js';
89
import { renderIcon } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
@@ -56,12 +57,11 @@ import { IViewsService } from '../../../services/views/common/viewsService.js';
5657
import { IExtensionsWorkbenchService } from '../../extensions/common/extensions.js';
5758
import { ChatAgentLocation, IChatAgentImplementation, IChatAgentRequest, IChatAgentResult, IChatAgentService, IChatWelcomeMessageContent } from '../common/chatAgents.js';
5859
import { ChatContextKeys } from '../common/chatContextKeys.js';
59-
import { ChatEntitlement, ChatEntitlementService, ChatSetupContext, ChatSetupRequests, IChatEntitlementService } from '../common/chatEntitlementService.js';
60+
import { ChatEntitlement, ChatEntitlementContext, ChatEntitlementRequests, ChatEntitlementService, IChatEntitlementService } from '../common/chatEntitlementService.js';
6061
import { IChatProgress, IChatProgressMessage, IChatWarningMessage } from '../common/chatService.js';
6162
import { CHAT_CATEGORY, CHAT_SETUP_ACTION_ID } from './actions/chatActions.js';
6263
import { ChatViewId, EditsViewId, ensureSideBarChatViewSize, preferCopilotEditsView, showCopilotView } from './chat.js';
6364
import { CHAT_EDITING_SIDEBAR_PANEL_ID, CHAT_SIDEBAR_PANEL_ID } from './chatViewPane.js';
64-
import './media/chatViewSetup.css';
6565
import { ChatViewsWelcomeExtensions, IChatViewsWelcomeContributionRegistry } from './viewsWelcome/chatViewsWelcome.js';
6666

6767
const defaultChat = {
@@ -89,7 +89,7 @@ const defaultChat = {
8989

9090
class SetupChatAgentImplementation implements IChatAgentImplementation {
9191

92-
static register(instantiationService: IInstantiationService, location: ChatAgentLocation, context: ChatSetupContext, controller: Lazy<ChatSetupController>): IDisposable {
92+
static register(instantiationService: IInstantiationService, location: ChatAgentLocation, context: ChatEntitlementContext, controller: Lazy<ChatSetupController>): IDisposable {
9393
return instantiationService.invokeFunction(accessor => {
9494
const chatAgentService = accessor.get(IChatAgentService);
9595

@@ -137,7 +137,7 @@ class SetupChatAgentImplementation implements IChatAgentImplementation {
137137
}
138138

139139
constructor(
140-
private readonly context: ChatSetupContext,
140+
private readonly context: ChatEntitlementContext,
141141
private readonly controller: Lazy<ChatSetupController>,
142142
@IInstantiationService private readonly instantiationService: IInstantiationService,
143143
@ILogService private readonly logService: ILogService,
@@ -158,7 +158,7 @@ class SetupChatAgentImplementation implements IChatAgentImplementation {
158158
case ChatSetupStep.SigningIn:
159159
progress({
160160
kind: 'progressMessage',
161-
content: new MarkdownString(localize('setupChatSignIn2', "Signing in to {0}...", ChatSetupRequests.providerId(this.configurationService) === defaultChat.enterpriseProviderId ? defaultChat.enterpriseProviderName : defaultChat.providerName)),
161+
content: new MarkdownString(localize('setupChatSignIn2', "Signing in to {0}...", ChatEntitlementRequests.providerId(this.configurationService) === defaultChat.enterpriseProviderId ? defaultChat.enterpriseProviderName : defaultChat.providerName)),
162162
} satisfies IChatProgressMessage);
163163
break;
164164
case ChatSetupStep.Installing:
@@ -208,7 +208,7 @@ class SetupChatAgentImplementation implements IChatAgentImplementation {
208208
class ChatSetupDialog {
209209

210210
constructor(
211-
private readonly context: ChatSetupContext,
211+
private readonly context: ChatEntitlementContext,
212212
@IDialogService private readonly dialogService: IDialogService,
213213
@IInstantiationService private readonly instantiationService: IInstantiationService,
214214
@ITelemetryService private readonly telemetryService: ITelemetryService
@@ -217,7 +217,7 @@ class ChatSetupDialog {
217217
async show(): Promise<boolean> {
218218
const res = await this.dialogService.prompt<boolean>({
219219
type: 'none',
220-
message: localize('copilotFree', "Use AI Features with Copilot for Free"),
220+
message: localize('copilotFree', "Welcome to Copilot"),
221221
cancelButton: {
222222
label: localize('cancel', "Cancel"),
223223
run: () => false
@@ -280,6 +280,12 @@ class ChatSetupDialog {
280280
)
281281
);
282282

283+
// Limited SKU
284+
if (this.context.state.entitlement !== ChatEntitlement.Pro && this.context.state.entitlement !== ChatEntitlement.Unavailable) {
285+
const free = localize({ key: 'free', comment: ['{Locked="[]({0})"}'] }, "$(sparkle-filled) We now offer [Copilot for free]({0}).", defaultChat.skusDocumentationUrl);
286+
element.appendChild($('p', undefined, disposables.add(markdown.render(new MarkdownString(free, { isTrusted: true, supportThemeIcons: true }))).element));
287+
}
288+
283289
// Terms
284290
const terms = localize({ key: 'terms', comment: ['{Locked="["}', '{Locked="]({0})"}', '{Locked="]({1})"}'] }, "By continuing, you agree to the [Terms]({0}) and [Privacy Policy]({1}).", defaultChat.termsStatementUrl, defaultChat.privacyStatementUrl);
285291
element.appendChild($('p.legal', undefined, disposables.add(markdown.render(new MarkdownString(terms, { isTrusted: true }))).element));
@@ -322,7 +328,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
322328
this.registerUrlLinkHandler();
323329
}
324330

325-
private registerSetupAgents(context: ChatSetupContext, controller: Lazy<ChatSetupController>): void {
331+
private registerSetupAgents(context: ChatEntitlementContext, controller: Lazy<ChatSetupController>): void {
326332
const registration = this._register(new MutableDisposable());
327333

328334
const updateRegistration = () => {
@@ -343,7 +349,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
343349
), () => updateRegistration()));
344350
}
345351

346-
private registerChatWelcome(context: ChatSetupContext, controller: Lazy<ChatSetupController>): void {
352+
private registerChatWelcome(context: ChatEntitlementContext, controller: Lazy<ChatSetupController>): void {
347353
Registry.as<IChatViewsWelcomeContributionRegistry>(ChatViewsWelcomeExtensions.ChatViewsWelcomeRegistry).register({
348354
title: localize('welcomeChat', "Welcome to Copilot"),
349355
when: ChatContextKeys.SetupViewCondition,
@@ -352,11 +358,13 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
352358
});
353359
}
354360

355-
private registerActions(context: ChatSetupContext, requests: ChatSetupRequests, controller: Lazy<ChatSetupController>): void {
356-
const chatSetupTriggerContext = ContextKeyExpr.or(
357-
ChatContextKeys.Setup.installed.negate(),
358-
ChatContextKeys.Setup.canSignUp
359-
);
361+
private registerActions(context: ChatEntitlementContext, requests: ChatEntitlementRequests, controller: Lazy<ChatSetupController>): void {
362+
const chatSetupTriggerContext = ContextKeyExpr.and(
363+
ChatContextKeys.Setup.fromDialog.negate(), // reduce noise when using the skeleton-view approach
364+
ContextKeyExpr.or(
365+
ChatContextKeys.Setup.installed.negate(),
366+
ChatContextKeys.Entitlement.canSignUp
367+
));
360368

361369
const CHAT_SETUP_ACTION_LABEL = localize2('triggerChatSetup', "Use AI Features with Copilot for Free...");
362370

@@ -494,8 +502,8 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
494502
category: localize2('chat.category', 'Chat'),
495503
f1: true,
496504
precondition: ContextKeyExpr.or(
497-
ChatContextKeys.Setup.canSignUp,
498-
ChatContextKeys.Setup.limited,
505+
ChatContextKeys.Entitlement.canSignUp,
506+
ChatContextKeys.Entitlement.limited,
499507
),
500508
menu: {
501509
id: MenuId.ChatTitleBarMenu,
@@ -597,8 +605,8 @@ class ChatSetupController extends Disposable {
597605
private willShutdown = false;
598606

599607
constructor(
600-
private readonly context: ChatSetupContext,
601-
private readonly requests: ChatSetupRequests,
608+
private readonly context: ChatEntitlementContext,
609+
private readonly requests: ChatEntitlementRequests,
602610
@ITelemetryService private readonly telemetryService: ITelemetryService,
603611
@IAuthenticationService private readonly authenticationService: IAuthenticationService,
604612
@IViewsService private readonly viewsService: IViewsService,
@@ -659,7 +667,7 @@ class ChatSetupController extends Disposable {
659667
let success = false;
660668
try {
661669
const setupFromDialog = Boolean(this.configurationService.getValue('chat.experimental.setupFromDialog'));
662-
const providerId = ChatSetupRequests.providerId(this.configurationService);
670+
const providerId = ChatEntitlementRequests.providerId(this.configurationService);
663671
let session: AuthenticationSession | undefined;
664672
let entitlement: ChatEntitlement | undefined;
665673

@@ -718,7 +726,7 @@ class ChatSetupController extends Disposable {
718726
if (!session && !this.willShutdown) {
719727
const { confirmed } = await this.dialogService.confirm({
720728
type: Severity.Error,
721-
message: localize('unknownSignInError', "Failed to sign in to {0}. Would you like to try again?", ChatSetupRequests.providerId(this.configurationService) === defaultChat.enterpriseProviderId ? defaultChat.enterpriseProviderName : defaultChat.providerName),
729+
message: localize('unknownSignInError', "Failed to sign in to {0}. Would you like to try again?", ChatEntitlementRequests.providerId(this.configurationService) === defaultChat.enterpriseProviderId ? defaultChat.enterpriseProviderName : defaultChat.providerName),
722730
detail: localize('unknownSignInErrorDetail', "You must be signed in to use Copilot."),
723731
primaryButton: localize('retry', "Retry")
724732
});
@@ -825,7 +833,7 @@ class ChatSetupWelcomeContent extends Disposable {
825833

826834
constructor(
827835
private readonly controller: ChatSetupController,
828-
private readonly context: ChatSetupContext,
836+
private readonly context: ChatEntitlementContext,
829837
@IInstantiationService private readonly instantiationService: IInstantiationService,
830838
@IContextMenuService private readonly contextMenuService: IContextMenuService,
831839
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -925,7 +933,7 @@ class ChatSetupWelcomeContent extends Disposable {
925933

926934
switch (this.controller.step) {
927935
case ChatSetupStep.SigningIn:
928-
buttonLabel = localize('setupChatSignIn', "$(loading~spin) Signing in to {0}...", ChatSetupRequests.providerId(this.configurationService) === defaultChat.enterpriseProviderId ? defaultChat.enterpriseProviderName : defaultChat.providerName);
936+
buttonLabel = localize('setupChatSignIn', "$(loading~spin) Signing in to {0}...", ChatEntitlementRequests.providerId(this.configurationService) === defaultChat.enterpriseProviderId ? defaultChat.enterpriseProviderName : defaultChat.providerName);
929937
break;
930938
case ChatSetupStep.Installing:
931939
buttonLabel = localize('setupChatInstalling', "$(loading~spin) Getting Copilot Ready...");

0 commit comments

Comments
 (0)