Skip to content

Commit 53e23e2

Browse files
authored
Adopt mcp token flag (take 2) (microsoft#252669)
* adopt mcp token flag (microsoft/vscode-internalbacklog#5514) * dont use constant to ChatMCP * use common/objects equals()
1 parent e1e851c commit 53e23e2

File tree

3 files changed

+56
-28
lines changed

3 files changed

+56
-28
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,9 @@ configurationRegistry.registerConfiguration({
258258
type: 'boolean',
259259
description: nls.localize('chat.mcp.enabled', "Enables integration with Model Context Protocol servers to provide additional tools and functionality."),
260260
default: true,
261-
tags: ['preview'],
262261
policy: {
263262
name: 'ChatMCP',
264263
minimumVersion: '1.99',
265-
previewFeature: true,
266-
defaultValue: false
267264
}
268265
},
269266
[mcpServerSamplingSection]: {

src/vs/workbench/services/accounts/common/defaultAccount.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface IDefaultAccount {
3636
readonly can_signup_for_limited?: boolean;
3737
readonly chat_enabled?: boolean;
3838
readonly chat_preview_features_enabled?: boolean;
39+
readonly mcp?: boolean;
3940
readonly analytics_tracking_id?: string;
4041
readonly limited_user_quotas?: {
4142
readonly chat: number;
@@ -189,15 +190,15 @@ export class DefaultAccountManagementContribution extends Disposable implements
189190
}
190191
}
191192

192-
private extractFromToken(token: string, key: string): string | undefined {
193+
private extractFromToken(token: string): Map<string, string> {
193194
const result = new Map<string, string>();
194195
const firstPart = token?.split(':')[0];
195196
const fields = firstPart?.split(';');
196197
for (const field of fields) {
197198
const [key, value] = field.split('=');
198199
result.set(key, value);
199200
}
200-
return result.get(key);
201+
return result;
201202
}
202203

203204
private async getDefaultAccountFromAuthenticatedSessions(authProviderId: string, enterpriseAuthProviderId: string, enterpriseAuthProviderConfig: string, scopes: string[], tokenEntitlementUrl: string, chatEntitlementUrl: string): Promise<IDefaultAccount | null> {
@@ -243,9 +244,12 @@ export class DefaultAccountManagementContribution extends Disposable implements
243244

244245
const chatData = await asJson<ITokenEntitlementsResponse>(chatContext);
245246
if (chatData) {
247+
const tokenMap = this.extractFromToken(chatData.token);
246248
return {
247249
// Editor preview features are disabled if the flag is present and set to 0
248-
chat_preview_features_enabled: this.extractFromToken(chatData.token, 'editor_preview_features') !== '0',
250+
chat_preview_features_enabled: tokenMap.get('editor_preview_features') !== '0',
251+
// MCP is disabled if the flag is present and set to 0
252+
mcp: tokenMap.get('mcp') !== '0',
249253
};
250254
}
251255
this.logService.error('Failed to fetch token entitlements', 'No data returned');

src/vs/workbench/services/policies/common/accountPolicyService.ts

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { IStringDictionary } from '../../../../base/common/collections.js';
7+
import { equals } from '../../../../base/common/objects.js';
78
import { ILogService } from '../../../../platform/log/common/log.js';
89
import { AbstractPolicyService, IPolicyService, PolicyDefinition } from '../../../../platform/policy/common/policy.js';
910
import { IDefaultAccountService } from '../../accounts/common/defaultAccount.js';
1011

12+
interface IAccountPolicy {
13+
readonly chatPreviewFeaturesEnabled: boolean;
14+
readonly mcpEnabled: boolean;
15+
}
16+
1117
export class AccountPolicyService extends AbstractPolicyService implements IPolicyService {
12-
private chatPreviewFeaturesEnabled: boolean = true;
18+
private accountPolicy: IAccountPolicy = {
19+
chatPreviewFeaturesEnabled: true,
20+
mcpEnabled: true
21+
};
1322
constructor(
1423
@ILogService private readonly logService: ILogService,
1524
@IDefaultAccountService private readonly defaultAccountService: IDefaultAccountService
@@ -18,43 +27,61 @@ export class AccountPolicyService extends AbstractPolicyService implements IPoli
1827

1928
this.defaultAccountService.getDefaultAccount()
2029
.then(account => {
21-
this._update(account?.chat_preview_features_enabled ?? true);
22-
this._register(this.defaultAccountService.onDidChangeDefaultAccount(account => this._update(account?.chat_preview_features_enabled ?? true)));
30+
this._update({
31+
chatPreviewFeaturesEnabled: account?.chat_preview_features_enabled ?? true,
32+
mcpEnabled: account?.mcp ?? true
33+
});
34+
this._register(this.defaultAccountService.onDidChangeDefaultAccount(
35+
account => this._update({
36+
chatPreviewFeaturesEnabled: account?.chat_preview_features_enabled ?? true,
37+
mcpEnabled: account?.mcp ?? true
38+
})
39+
));
2340
});
2441
}
2542

26-
private _update(chatPreviewFeaturesEnabled: boolean | undefined) {
27-
const newValue = (chatPreviewFeaturesEnabled === undefined) || chatPreviewFeaturesEnabled;
28-
if (this.chatPreviewFeaturesEnabled !== newValue) {
29-
this.chatPreviewFeaturesEnabled = newValue;
43+
private _update(updatedPolicy: IAccountPolicy): void {
44+
if (!equals(this.accountPolicy, updatedPolicy)) {
45+
this.accountPolicy = updatedPolicy;
3046
this._updatePolicyDefinitions(this.policyDefinitions);
3147
}
3248
}
3349

3450
protected async _updatePolicyDefinitions(policyDefinitions: IStringDictionary<PolicyDefinition>): Promise<void> {
3551
this.logService.trace(`AccountPolicyService#_updatePolicyDefinitions: Got ${Object.keys(policyDefinitions).length} policy definitions`);
52+
const updated: string[] = [];
3653

37-
const update: string[] = [];
38-
for (const key in policyDefinitions) {
39-
const policy = policyDefinitions[key];
40-
if (policy.previewFeature) {
41-
if (this.chatPreviewFeaturesEnabled) {
54+
const updateIfNeeded = (key: string, policy: PolicyDefinition, isFeatureEnabled: boolean): void => {
55+
if (isFeatureEnabled) {
56+
// Clear the policy if it is set
57+
if (this.policies.has(key)) {
4258
this.policies.delete(key);
43-
update.push(key);
44-
continue;
59+
updated.push(key);
4560
}
46-
const defaultValue = policy.defaultValue;
47-
const updatedValue = defaultValue === undefined ? false : defaultValue;
48-
if (this.policies.get(key) === updatedValue) {
49-
continue;
61+
} else {
62+
// Enforce the defaultValue if not already set
63+
const updatedValue = policy.defaultValue === undefined ? false : policy.defaultValue;
64+
if (this.policies.get(key) !== updatedValue) {
65+
this.policies.set(key, updatedValue);
66+
updated.push(key);
5067
}
51-
this.policies.set(key, updatedValue);
52-
update.push(key);
68+
}
69+
};
70+
71+
for (const key in policyDefinitions) {
72+
const policy = policyDefinitions[key];
73+
// Preview Features
74+
if (policy.previewFeature) {
75+
updateIfNeeded(key, policy, this.accountPolicy?.chatPreviewFeaturesEnabled);
76+
}
77+
// MCP
78+
else if (key === 'ChatMCP') {
79+
updateIfNeeded(key, policy, this.accountPolicy?.mcpEnabled);
5380
}
5481
}
5582

56-
if (update.length) {
57-
this._onDidChange.fire(update);
83+
if (updated.length) {
84+
this._onDidChange.fire(updated);
5885
}
5986
}
6087
}

0 commit comments

Comments
 (0)