From ae66d87d47f69b8d229617cf4e21795d6f79c4be Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 8 Apr 2026 12:51:18 +0200 Subject: [PATCH] disable chat extension by default and adopt accordingly --- .../parts/editor/editorGroupWatermark.ts | 2 +- .../chat/browser/actions/chatActions.ts | 2 -- .../agentSessionsExperiments.contribution.ts | 1 - .../browser/chatParticipant.contribution.ts | 1 - .../chatSetup/chatSetupContributions.ts | 10 +++---- .../contrib/scm/browser/scm.contribution.ts | 1 - .../workbench/contrib/scm/browser/scmInput.ts | 1 - .../chat/common/chatEntitlementService.ts | 2 +- .../browser/extensionEnablementService.ts | 30 +++++++++++++++++++ .../extensionEnablementService.test.ts | 3 +- 10 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts index 03bfed510efa8..b949732eb1f7d 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts @@ -26,7 +26,7 @@ interface WatermarkEntry { }; } -const showChatContextKey = ContextKeyExpr.and(ContextKeyExpr.equals('chatSetupHidden', false), ContextKeyExpr.equals('chatSetupDisabled', false)); +const showChatContextKey = ContextKeyExpr.and(ContextKeyExpr.equals('chatSetupHidden', false)); const openChat: WatermarkEntry = { text: localize('watermark.openChat', "Open Chat"), id: 'workbench.action.chat.open', when: { native: showChatContextKey, web: showChatContextKey } }; const showCommands: WatermarkEntry = { text: localize('watermark.showCommands', "Show All Commands"), id: 'workbench.action.showCommands' }; diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index cd85b8ebc5841..75abd21edf75d 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -205,7 +205,6 @@ abstract class OpenChatGlobalAction extends Action2 { category: CHAT_CATEGORY, precondition: ContextKeyExpr.and( ChatContextKeys.Setup.hidden.negate(), - ChatContextKeys.Setup.disabled.negate() ) }); } @@ -1728,7 +1727,6 @@ MenuRegistry.appendMenuItem(MenuId.EditorContext, { title: localize('generateCode', "Generate Code"), when: ContextKeyExpr.and( ChatContextKeys.Setup.hidden.negate(), - ChatContextKeys.Setup.disabled.negate() ) }); diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionsExperiments.contribution.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionsExperiments.contribution.ts index 4e1d91d492711..8b8e25bb3d160 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionsExperiments.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionsExperiments.contribution.ts @@ -266,7 +266,6 @@ MenuRegistry.appendMenuItem(MenuId.TitleBar, { ChatContextKeys.supported, ContextKeyExpr.and( ChatContextKeys.Setup.hidden.negate(), - ChatContextKeys.Setup.disabled.negate() ), ContextKeyExpr.has('config.window.commandCenter').negate(), ), diff --git a/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts b/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts index ddb5df4184759..6bbb105d0c7eb 100644 --- a/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.ts @@ -71,7 +71,6 @@ const chatViewDescriptor: IViewDescriptor = { when: ContextKeyExpr.or( ContextKeyExpr.or( ChatContextKeys.Setup.hidden, - ChatContextKeys.Setup.disabled )?.negate(), ChatContextKeys.panelParticipantRegistered, ChatContextKeys.extensionInvalid diff --git a/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupContributions.ts b/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupContributions.ts index 24c12b387621c..c3e121d5dc23e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupContributions.ts +++ b/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupContributions.ts @@ -113,7 +113,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr // Agent + Tools { - if (!context.state.hidden && !context.state.disabled) { + if (!context.state.hidden) { // Default Agents (always, even if installed to allow for speedy requests right on startup) if (!defaultAgentDisposables.value) { @@ -154,14 +154,14 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr vscodeAgentDisposables.clear(); } - if (context.state.completed && !context.state.disabled) { + if (context.state.completed) { vscodeAgentDisposables.clear(); // we need to do this to prevent showing duplicate agent/tool entries in the list } } // Rename Provider { - if (!context.state.completed && !context.state.hidden && !context.state.disabled) { + if (!context.state.completed && !context.state.hidden) { if (!renameProviderDisposables.value) { renameProviderDisposables.value = AINewSymbolNamesProvider.registerProvider(this.instantiationService, context, controller); } @@ -172,7 +172,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr // Code Actions Provider { - if (!context.state.completed && !context.state.hidden && !context.state.disabled) { + if (!context.state.completed && !context.state.hidden) { if (!codeActionsProviderDisposables.value) { codeActionsProviderDisposables.value = ChatCodeActionsProvider.registerProvider(this.instantiationService); } @@ -232,7 +232,6 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr f1: true, precondition: ContextKeyExpr.or( ChatContextKeys.Setup.hidden, - ChatContextKeys.Setup.disabled, ChatContextKeys.Setup.untrusted, ChatContextKeys.Setup.completed.negate(), ChatContextKeys.Entitlement.canSignUp @@ -559,7 +558,6 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr const internalGenerateCodeContext = ContextKeyExpr.and( ChatContextKeys.Setup.hidden.negate(), - ChatContextKeys.Setup.disabled.negate(), ChatContextKeys.Setup.completed.negate(), ); diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index efcd3bac3cd26..3d6e43f40f8a0 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -702,7 +702,6 @@ registerAction2(class extends Action2 { id: MenuId.EditorContent, when: ContextKeyExpr.and( ChatContextKeys.Setup.hidden.negate(), - ChatContextKeys.Setup.disabled.negate(), ChatContextKeys.Setup.completed.negate(), ContextKeyExpr.in(ResourceContextKey.Resource.key, 'git.mergeChanges'), ContextKeyExpr.equals('git.activeResourceHasMergeConflicts', true) diff --git a/src/vs/workbench/contrib/scm/browser/scmInput.ts b/src/vs/workbench/contrib/scm/browser/scmInput.ts index 8c014fa20d402..ac5d91a43bc11 100644 --- a/src/vs/workbench/contrib/scm/browser/scmInput.ts +++ b/src/vs/workbench/contrib/scm/browser/scmInput.ts @@ -847,7 +847,6 @@ registerAction2(class extends Action2 { id: MenuId.SCMInputBox, when: ContextKeyExpr.and( ChatContextKeys.Setup.hidden.negate(), - ChatContextKeys.Setup.disabled.negate(), ChatContextKeys.Setup.completed.negate(), ContextKeyExpr.equals('scmProvider', 'git') ) diff --git a/src/vs/workbench/services/chat/common/chatEntitlementService.ts b/src/vs/workbench/services/chat/common/chatEntitlementService.ts index 961247310655d..929fb8e1ab7c0 100644 --- a/src/vs/workbench/services/chat/common/chatEntitlementService.ts +++ b/src/vs/workbench/services/chat/common/chatEntitlementService.ts @@ -241,7 +241,7 @@ function isAnonymous(configurationService: IConfigurationService, entitlement: C return false; // only consider signed out users } - if (sentiment.hidden || sentiment.disabled) { + if (sentiment.hidden) { return false; // only consider enabled scenarios } diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts index 7ab99c1774418..944f45a82ba8c 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts @@ -33,6 +33,7 @@ import { isString } from '../../../../base/common/types.js'; import { Delayer } from '../../../../base/common/async.js'; import { IProductService } from '../../../../platform/product/common/productService.js'; import { isWeb } from '../../../../base/common/platform.js'; +import { ChatEntitlementService, IChatEntitlementService } from '../../chat/common/chatEntitlementService.js'; const SOURCE = 'IWorkbenchExtensionEnablementService'; @@ -75,6 +76,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench @IWorkspaceTrustManagementService private readonly workspaceTrustManagementService: IWorkspaceTrustManagementService, @IWorkspaceTrustRequestService private readonly workspaceTrustRequestService: IWorkspaceTrustRequestService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, + @IChatEntitlementService chatEntitlementService: IChatEntitlementService, @IInstantiationService instantiationService: IInstantiationService, @ILogService private readonly logService: ILogService, @IProductService productService: IProductService @@ -133,6 +135,34 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench }); }); } + + if (!this.environmentService.isSessionsWindow) { + const builtinChatExtensionEnablementMigrationKey = 'builtinChatExtensionEnablementMigration'; + const builtinChatExtensionEnablementMigration = this.storageService.getBoolean(builtinChatExtensionEnablementMigrationKey, StorageScope.PROFILE) === true; + if (!builtinChatExtensionEnablementMigration) { + this.logService.debug('Running builtin chat extension enablement migration'); + this.storageService.store(builtinChatExtensionEnablementMigrationKey, true, StorageScope.PROFILE, StorageTarget.MACHINE); + const context = (chatEntitlementService as ChatEntitlementService).context; + if (context) { + if (context.value.state.completed) { + if (this._isDisabledGlobally({ id: this._chatExtensionId })) { + if (this.configurationService.getValue('chat.disableAIFeatures') !== true) { + this.logService.debug('Disabling AI features because builtin chat extension is disabled'); + this.configurationService.updateValue('chat.disableAIFeatures', true) + .catch(err => this.logService.error('Failed to update chat.disableAIFeatures setting during builtin chat extension enablement migration', err)); + } + } + } else { + try { + this.logService.debug('Disabling builtin chat extension as chat set up is not completed'); + this._disableExtension({ id: this._chatExtensionId }); + } catch (error) { + this.logService.error('Failed to disable builtin chat extension during enablement migration', error); + } + } + } + } + } } private get hasWorkspace(): boolean { diff --git a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts index 8a973961f2b30..c618f6fbd31e4 100644 --- a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts @@ -31,7 +31,7 @@ import { mock } from '../../../../../base/test/common/mock.js'; import { IExtensionBisectService } from '../../browser/extensionBisect.js'; import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService, WorkspaceTrustRequestOptions } from '../../../../../platform/workspace/common/workspaceTrust.js'; import { ExtensionManifestPropertiesService, IExtensionManifestPropertiesService } from '../../../extensions/common/extensionManifestPropertiesService.js'; -import { TestContextService, TestProductService, TestWorkspaceTrustEnablementService, TestWorkspaceTrustManagementService } from '../../../../test/common/workbenchTestServices.js'; +import { TestChatEntitlementService, TestContextService, TestProductService, TestWorkspaceTrustEnablementService, TestWorkspaceTrustManagementService } from '../../../../test/common/workbenchTestServices.js'; import { TestWorkspace } from '../../../../../platform/workspace/test/common/testWorkspace.js'; import { ExtensionManagementService } from '../../common/extensionManagementService.js'; import { ILogService, NullLogService } from '../../../../../platform/log/common/log.js'; @@ -97,6 +97,7 @@ export class TestExtensionEnablementService extends ExtensionEnablementService { workspaceTrustManagementService, new class extends mock() { override requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise { return Promise.resolve(true); } }, instantiationService.get(IExtensionManifestPropertiesService) || instantiationService.stub(IExtensionManifestPropertiesService, disposables.add(new ExtensionManifestPropertiesService(TestProductService, new TestConfigurationService(), new TestWorkspaceTrustEnablementService(), new NullLogService()))), + new TestChatEntitlementService(), instantiationService, new NullLogService(), productService