Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion product.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@
"resolveMergeConflictsCommand": "github.copilot.git.resolveMergeConflicts",
"completionsAdvancedSetting": "github.copilot.advanced",
"completionsEnablementSetting": "github.copilot.enable",
"nextEditSuggestionsSetting": "github.copilot.nextEditSuggestions.enabled"
"nextEditSuggestionsSetting": "github.copilot.nextEditSuggestions.enabled",
"tokenEntitlementUrl": "https://api.github.com/copilot_internal/v2/token",
"mcpRegistryDataUrl": "https://api.github.com/copilot/mcp_registry"
},
"trustedExtensionAuthAccess": {
"github": [
Expand Down
63 changes: 49 additions & 14 deletions src/vs/base/common/defaultAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface IDefaultAccount {
readonly sessionId: string;
readonly enterprise: boolean;
readonly access_type_sku?: string;
readonly copilot_plan?: string;
readonly assigned_date?: string;
readonly can_signup_for_limited?: boolean;
readonly chat_enabled?: boolean;
readonly chat_preview_features_enabled?: boolean;
readonly mcp?: boolean;
readonly mcpRegistryUrl?: string;
readonly mcpAccess?: 'allow_all' | 'registry_only';
readonly analytics_tracking_id?: string;
export interface IQuotaSnapshotData {
readonly entitlement: number;
readonly overage_count: number;
readonly overage_permitted: boolean;
readonly percent_remaining: number;
readonly remaining: number;
readonly unlimited: boolean;
}

export interface ILegacyQuotaSnapshotData {
readonly limited_user_quotas?: {
readonly chat: number;
readonly completions: number;
Expand All @@ -24,6 +21,44 @@ export interface IDefaultAccount {
readonly chat: number;
readonly completions: number;
};
readonly limited_user_reset_date?: string;
}

export interface IEntitlementsData extends ILegacyQuotaSnapshotData {
readonly access_type_sku: string;
readonly assigned_date: string;
readonly can_signup_for_limited: boolean;
readonly chat_enabled: boolean;
readonly copilot_plan: string;
readonly organization_login_list: string[];
readonly analytics_tracking_id: string;
readonly limited_user_reset_date?: string; // for Copilot Free
readonly quota_reset_date?: string; // for all other Copilot SKUs
readonly quota_reset_date_utc?: string; // for all other Copilot SKUs (includes time)
readonly quota_snapshots?: {
chat?: IQuotaSnapshotData;
completions?: IQuotaSnapshotData;
premium_interactions?: IQuotaSnapshotData;
};
}

export interface IPolicyData {
readonly mcp?: boolean;
readonly chat_preview_features_enabled?: boolean;
readonly chat_agent_enabled?: boolean;
readonly mcpRegistryUrl?: string;
readonly mcpAccess?: 'allow_all' | 'registry_only';
}

export interface IDefaultAccountAuthenticationProvider {
readonly id: string;
readonly name: string;
readonly enterprise: boolean;
}

export interface IDefaultAccount {
readonly authenticationProvider: IDefaultAccountAuthenticationProvider;
readonly sessionId: string;
readonly enterprise: boolean;
readonly entitlementsData?: IEntitlementsData | null;
readonly policyData?: IPolicyData;
}
17 changes: 2 additions & 15 deletions src/vs/base/common/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ export interface IProductConfiguration {
readonly msftInternalDomains?: string[];
readonly linkProtectionTrustedDomains?: readonly string[];

readonly defaultAccount?: IDefaultAccountConfig;
readonly authClientIdMetadataUrl?: string;

readonly 'configurationSync.store'?: ConfigurationSyncStore;
Expand All @@ -231,20 +230,6 @@ export interface IProductConfiguration {
readonly extensionConfigurationPolicy?: IStringDictionary<IPolicy>;
}

export interface IDefaultAccountConfig {
readonly preferredExtensions: string[];
readonly authenticationProvider: {
readonly id: string;
readonly enterpriseProviderId: string;
readonly enterpriseProviderConfig: string;
readonly enterpriseProviderUriSetting: string;
readonly scopes: string[][];
};
readonly tokenEntitlementUrl: string;
readonly chatEntitlementUrl: string;
readonly mcpRegistryDataUrl: string;
}

export interface ITunnelApplicationConfig {
authenticationProviders: IStringDictionary<{ scopes: string[] }>;
editorWebUrl: string;
Expand Down Expand Up @@ -377,6 +362,8 @@ export interface IDefaultChatAgent {

readonly entitlementUrl: string;
readonly entitlementSignupLimitedUrl: string;
readonly tokenEntitlementUrl: string;
readonly mcpRegistryDataUrl: string;

readonly chatQuotaExceededContext: string;
readonly completionsQuotaExceededContext: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

import './nativeEditContext.css';
import { isFirefox } from '../../../../../base/browser/browser.js';
import { addDisposableListener, getActiveElement, getWindow, getWindowId } from '../../../../../base/browser/dom.js';
import { addDisposableListener, getActiveElement, getWindow, getWindowId, scheduleAtNextAnimationFrame } from '../../../../../base/browser/dom.js';
import { FastDomNode } from '../../../../../base/browser/fastDomNode.js';
import { StandardKeyboardEvent } from '../../../../../base/browser/keyboardEvent.js';
import { KeyCode } from '../../../../../base/common/keyCodes.js';
import { IDisposable } from '../../../../../base/common/lifecycle.js';
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
import { EditorOption } from '../../../../common/config/editorOptions.js';
import { EndOfLinePreference, IModelDeltaDecoration } from '../../../../common/model.js';
Expand Down Expand Up @@ -68,6 +69,7 @@ export class NativeEditContext extends AbstractEditContext {
private _targetWindowId: number = -1;
private _scrollTop: number = 0;
private _scrollLeft: number = 0;
private _selectionAndControlBoundsUpdateDisposable: IDisposable | undefined;

private readonly _focusTracker: FocusTracker;

Expand Down Expand Up @@ -233,6 +235,8 @@ export class NativeEditContext extends AbstractEditContext {
this.domNode.domNode.blur();
this.domNode.domNode.remove();
this._imeTextArea.domNode.remove();
this._selectionAndControlBoundsUpdateDisposable?.dispose();
this._selectionAndControlBoundsUpdateDisposable = undefined;
super.dispose();
}

Expand Down Expand Up @@ -505,7 +509,19 @@ export class NativeEditContext extends AbstractEditContext {
}
}

private _updateSelectionAndControlBoundsAfterRender() {
private _updateSelectionAndControlBoundsAfterRender(): void {
if (this._selectionAndControlBoundsUpdateDisposable) {
return;
}
// Schedule this work after render so we avoid triggering a layout while still painting.
const targetWindow = getWindow(this.domNode.domNode);
this._selectionAndControlBoundsUpdateDisposable = scheduleAtNextAnimationFrame(targetWindow, () => {
this._selectionAndControlBoundsUpdateDisposable = undefined;
this._applySelectionAndControlBounds();
});
}

private _applySelectionAndControlBounds(): void {
const options = this._context.configuration.options;
const contentLeft = options.get(EditorOption.layoutInfo).contentLeft;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import './textAreaEditContext.css';
import * as nls from '../../../../../nls.js';
import * as browser from '../../../../../base/browser/browser.js';
import { scheduleAtNextAnimationFrame, getWindow } from '../../../../../base/browser/dom.js';
import { FastDomNode, createFastDomNode } from '../../../../../base/browser/fastDomNode.js';
import { IKeyboardEvent } from '../../../../../base/browser/keyboardEvent.js';
import * as platform from '../../../../../base/common/platform.js';
Expand All @@ -31,6 +32,7 @@ import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from '../../../../../base/browser/ui
import { TokenizationRegistry } from '../../../../common/languages.js';
import { ColorId, ITokenPresentation } from '../../../../common/encodedTokenAttributes.js';
import { Color } from '../../../../../base/common/color.js';
import { IDisposable } from '../../../../../base/common/lifecycle.js';
import { IME } from '../../../../../base/common/ime.js';
import { IKeybindingService } from '../../../../../platform/keybinding/common/keybinding.js';
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
Expand Down Expand Up @@ -139,6 +141,7 @@ export class TextAreaEditContext extends AbstractEditContext {
* This is useful for hit-testing and determining the mouse position.
*/
private _lastRenderPosition: Position | null;
private _scheduledRender: IDisposable | null = null;

public readonly textArea: FastDomNode<HTMLTextAreaElement>;
public readonly textAreaCover: FastDomNode<HTMLElement>;
Expand Down Expand Up @@ -459,6 +462,8 @@ export class TextAreaEditContext extends AbstractEditContext {
}

public override dispose(): void {
this._scheduledRender?.dispose();
this._scheduledRender = null;
super.dispose();
this.textArea.domNode.remove();
this.textAreaCover.domNode.remove();
Expand Down Expand Up @@ -682,7 +687,20 @@ export class TextAreaEditContext extends AbstractEditContext {

public render(ctx: RestrictedRenderingContext): void {
this._textAreaInput.writeNativeTextAreaContent('render');
this._render();
this._scheduleRender();
}

// Delay expensive DOM updates until the next animation frame to reduce reflow pressure.
private _scheduleRender(): void {
if (this._scheduledRender) {
return;
}

const targetWindow = getWindow(this.textArea.domNode);
this._scheduledRender = scheduleAtNextAnimationFrame(targetWindow, () => {
this._scheduledRender = null;
this._render();
});
}

private _render(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1279,8 +1279,8 @@ export function isSuggestionInViewport(editor: ICodeEditor, suggestion: InlineSu
}

function skuFromAccount(account: IDefaultAccount | null): InlineSuggestSku | undefined {
if (account?.access_type_sku && account?.copilot_plan) {
return { type: account.access_type_sku, plan: account.copilot_plan };
if (account?.entitlementsData?.access_type_sku && account?.entitlementsData?.copilot_plan) {
return { type: account.entitlementsData.access_type_sku, plan: account.entitlementsData.copilot_plan };
}
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ async function withAsyncTestCodeEditorAndInlineCompletionsModel(
[IDefaultAccountService, new class extends mock<IDefaultAccountService>() {
override onDidChangeDefaultAccount = Event.None;
override getDefaultAccount = async () => null;
override setDefaultAccount = () => { };
override setDefaultAccountProvider = () => { };
}],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,10 @@ export async function withAsyncTestCodeEditorAndInlineCompletionsModel<T>(
_serviceBrand: undefined,
onDidChangeDefaultAccount: Event.None,
getDefaultAccount: async () => null,
setDefaultAccount: () => { },
setDefaultAccountProvider: () => { },
getDefaultAccountAuthenticationProvider: () => { return { id: 'mockProvider', name: 'Mock Provider', enterprise: false }; },
refresh: async () => { return null; },
signIn: async () => { return null; },
});

const d = languageFeaturesService.inlineCompletionsProvider.register({ pattern: '**' }, options.provider);
Expand Down
16 changes: 14 additions & 2 deletions src/vs/editor/standalone/browser/standaloneServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ import { IDataChannelService, NullDataChannelService } from '../../../platform/d
import { IWebWorkerService } from '../../../platform/webWorker/browser/webWorkerService.js';
import { StandaloneWebWorkerService } from './services/standaloneWebWorkerService.js';
import { IDefaultAccountService } from '../../../platform/defaultAccount/common/defaultAccount.js';
import { IDefaultAccount } from '../../../base/common/defaultAccount.js';
import { IDefaultAccount, IDefaultAccountAuthenticationProvider } from '../../../base/common/defaultAccount.js';

class SimpleModel implements IResolvedTextEditorModel {

Expand Down Expand Up @@ -1118,9 +1118,21 @@ class StandaloneDefaultAccountService implements IDefaultAccountService {
return null;
}

setDefaultAccount(account: IDefaultAccount | null): void {
setDefaultAccountProvider(): void {
// no-op
}

async refresh(): Promise<IDefaultAccount | null> {
return null;
}

getDefaultAccountAuthenticationProvider(): IDefaultAccountAuthenticationProvider {
return { id: 'default', name: 'Default', enterprise: false };
}

async signIn(): Promise<IDefaultAccount | null> {
return null;
}
}

export interface IEditorOverrideServices {
Expand Down
18 changes: 13 additions & 5 deletions src/vs/platform/defaultAccount/common/defaultAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@

import { createDecorator } from '../../instantiation/common/instantiation.js';
import { Event } from '../../../base/common/event.js';
import { IDefaultAccount } from '../../../base/common/defaultAccount.js';
import { IDefaultAccount, IDefaultAccountAuthenticationProvider } from '../../../base/common/defaultAccount.js';

export interface IDefaultAccountProvider {
readonly defaultAccount: IDefaultAccount | null;
readonly onDidChangeDefaultAccount: Event<IDefaultAccount | null>;
getDefaultAccountAuthenticationProvider(): IDefaultAccountAuthenticationProvider;
refresh(): Promise<IDefaultAccount | null>;
signIn(options?: { additionalScopes?: readonly string[];[key: string]: unknown }): Promise<IDefaultAccount | null>;
}

export const IDefaultAccountService = createDecorator<IDefaultAccountService>('defaultAccountService');

export interface IDefaultAccountService {

readonly _serviceBrand: undefined;

readonly onDidChangeDefaultAccount: Event<IDefaultAccount | null>;

getDefaultAccount(): Promise<IDefaultAccount | null>;
setDefaultAccount(account: IDefaultAccount | null): void;
getDefaultAccountAuthenticationProvider(): IDefaultAccountAuthenticationProvider;
setDefaultAccountProvider(provider: IDefaultAccountProvider): void;
refresh(): Promise<IDefaultAccount | null>;
signIn(options?: { additionalScopes?: readonly string[];[key: string]: unknown }): Promise<IDefaultAccount | null>;
}
17 changes: 16 additions & 1 deletion src/vs/platform/product/common/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,22 @@ else {
reportIssueUrl: 'https://github.com/microsoft/vscode/issues/new',
licenseName: 'MIT',
licenseUrl: 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
serverLicenseUrl: 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt'
serverLicenseUrl: 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
defaultChatAgent: {
extensionId: 'GitHub.copilot',
chatExtensionId: 'GitHub.copilot-chat',
provider: {
default: {
id: 'github',
name: 'GitHub',
},
enterprise: {
id: 'github-enterprise',
name: 'GitHub Enterprise',
}
},
providerScopes: []
}
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/web.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export class BrowserMain extends Disposable {
this._register(RemoteFileSystemProviderClient.register(remoteAgentService, fileService, logService));

// Default Account
const defaultAccountService = this._register(new DefaultAccountService());
const defaultAccountService = this._register(new DefaultAccountService(productService));
serviceCollection.set(IDefaultAccountService, defaultAccountService);

// Policies
Expand Down
10 changes: 5 additions & 5 deletions src/vs/workbench/contrib/chat/browser/chat.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ configurationRegistry.registerConfiguration({
name: 'ChatToolsAutoApprove',
category: PolicyCategory.InteractiveSession,
minimumVersion: '1.99',
value: (account) => account.chat_preview_features_enabled === false ? false : undefined,
value: (account) => account.policyData?.chat_preview_features_enabled === false ? false : undefined,
localization: {
description: {
key: 'autoApprove2.description',
Expand Down Expand Up @@ -445,10 +445,10 @@ configurationRegistry.registerConfiguration({
category: PolicyCategory.InteractiveSession,
minimumVersion: '1.99',
value: (account) => {
if (account.mcp === false) {
if (account.policyData?.mcp === false) {
return McpAccessValue.None;
}
if (account.mcpAccess === 'registry_only') {
if (account.policyData?.mcpAccess === 'registry_only') {
return McpAccessValue.Registry;
}
return undefined;
Expand Down Expand Up @@ -559,7 +559,7 @@ configurationRegistry.registerConfiguration({
name: 'ChatAgentMode',
category: PolicyCategory.InteractiveSession,
minimumVersion: '1.99',
value: (account) => account.chat_agent_enabled === false ? false : undefined,
value: (account) => account.policyData?.chat_agent_enabled === false ? false : undefined,
localization: {
description: {
key: 'chat.agent.enabled.description',
Expand Down Expand Up @@ -619,7 +619,7 @@ configurationRegistry.registerConfiguration({
name: 'McpGalleryServiceUrl',
category: PolicyCategory.InteractiveSession,
minimumVersion: '1.101',
value: (account) => account.mcpRegistryUrl,
value: (account) => account.policyData?.mcpRegistryUrl,
localization: {
description: {
key: 'mcp.gallery.serviceUrl',
Expand Down
Loading
Loading