Path: blob/main/extensions/copilot/src/lib/node/chatLibMain.ts
13394 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import type * as vscode from 'vscode';6import { DocumentSelector, Position } from 'vscode-languageserver-protocol';7import { GhostTextLogContext } from '../../extension/completions-core/common/ghostTextContext';8import { CompletionsTelemetryServiceBridge, ICompletionsTelemetryService } from '../../extension/completions-core/vscode-node/bridge/src/completionsTelemetryServiceBridge';9import { CopilotExtensionStatus, ICompletionsExtensionStatus } from '../../extension/completions-core/vscode-node/extension/src/extensionStatus';10import { CopilotTokenManagerImpl, ICompletionsCopilotTokenManager } from '../../extension/completions-core/vscode-node/lib/src/auth/copilotTokenManager';11import { ICompletionsCitationManager, IPCitationDetail, IPDocumentCitation } from '../../extension/completions-core/vscode-node/lib/src/citationManager';12import { CompletionNotifier, ICompletionsNotifierService } from '../../extension/completions-core/vscode-node/lib/src/completionNotifier';13import { ICompletionsObservableWorkspace } from '../../extension/completions-core/vscode-node/lib/src/completionsObservableWorkspace';14import { BuildInfo, BuildType, ConfigKeyType, DefaultsOnlyConfigProvider, EditorInfo, EditorPluginInfo, ICompletionsConfigProvider, ICompletionsEditorAndPluginInfo, InMemoryConfigProvider } from '../../extension/completions-core/vscode-node/lib/src/config';15import { ICompletionsUserErrorNotifierService, UserErrorNotifier } from '../../extension/completions-core/vscode-node/lib/src/error/userErrorNotifier';16import { Features } from '../../extension/completions-core/vscode-node/lib/src/experiments/features';17import { ICompletionsFeaturesService } from '../../extension/completions-core/vscode-node/lib/src/experiments/featuresService';18import { FileReader, ICompletionsFileReaderService } from '../../extension/completions-core/vscode-node/lib/src/fileReader';19import { ICompletionsFileSystemService } from '../../extension/completions-core/vscode-node/lib/src/fileSystem';20import { AsyncCompletionManager, ICompletionsAsyncManagerService } from '../../extension/completions-core/vscode-node/lib/src/ghostText/asyncCompletions';21import { CompletionsCache, ICompletionsCacheService } from '../../extension/completions-core/vscode-node/lib/src/ghostText/completionsCache';22import { ConfigBlockModeConfig, ICompletionsBlockModeConfig } from '../../extension/completions-core/vscode-node/lib/src/ghostText/configBlockMode';23import { CopilotCompletion } from '../../extension/completions-core/vscode-node/lib/src/ghostText/copilotCompletion';24import { CurrentGhostText, ICompletionsCurrentGhostText } from '../../extension/completions-core/vscode-node/lib/src/ghostText/current';25import { GetGhostTextOptions } from '../../extension/completions-core/vscode-node/lib/src/ghostText/ghostText';26import { ICompletionsLastGhostText, LastGhostText } from '../../extension/completions-core/vscode-node/lib/src/ghostText/last';27import { ITextEditorOptions } from '../../extension/completions-core/vscode-node/lib/src/ghostText/normalizeIndent';28import { ICompletionsSpeculativeRequestCache, SpeculativeRequestCache } from '../../extension/completions-core/vscode-node/lib/src/ghostText/speculativeRequestCache';29import { GhostText } from '../../extension/completions-core/vscode-node/lib/src/inlineCompletion';30import { LocalFileSystem } from '../../extension/completions-core/vscode-node/lib/src/localFileSystem';31import { LogLevel as CompletionsLogLevel, ICompletionsLogTargetService } from '../../extension/completions-core/vscode-node/lib/src/logger';32import { ICompletionsFetcherService } from '../../extension/completions-core/vscode-node/lib/src/networking';33import { ActionItem, ICompletionsNotificationSender } from '../../extension/completions-core/vscode-node/lib/src/notificationSender';34import { ICompletionsOpenAIFetcherService, LiveOpenAIFetcher } from '../../extension/completions-core/vscode-node/lib/src/openai/fetch';35import { AvailableModelsManager, ICompletionsModelManagerService } from '../../extension/completions-core/vscode-node/lib/src/openai/model';36import { ICompletionsStatusReporter, StatusChangedEvent, StatusReporter } from '../../extension/completions-core/vscode-node/lib/src/progress';37import { CompletionsPromptFactory, ICompletionsPromptFactoryService } from '../../extension/completions-core/vscode-node/lib/src/prompt/completionsPromptFactory/completionsPromptFactory';38import { ContextProviderBridge, ICompletionsContextProviderBridgeService } from '../../extension/completions-core/vscode-node/lib/src/prompt/components/contextProviderBridge';39import { CachedContextProviderRegistry, CoreContextProviderRegistry, DefaultContextProvidersContainer, ICompletionsContextProviderRegistryService, ICompletionsDefaultContextProviders } from '../../extension/completions-core/vscode-node/lib/src/prompt/contextProviderRegistry';40import { ContextProviderStatistics, ICompletionsContextProviderService } from '../../extension/completions-core/vscode-node/lib/src/prompt/contextProviderStatistics';41import { FullRecentEditsProvider, ICompletionsRecentEditsProviderService } from '../../extension/completions-core/vscode-node/lib/src/prompt/recentEdits/recentEditsProvider';42import { CompositeRelatedFilesProvider } from '../../extension/completions-core/vscode-node/lib/src/prompt/similarFiles/compositeRelatedFilesProvider';43import { ICompletionsRelatedFilesProviderService } from '../../extension/completions-core/vscode-node/lib/src/prompt/similarFiles/relatedFiles';44import { ICompletionsTelemetryUserConfigService, TelemetryUserConfig } from '../../extension/completions-core/vscode-node/lib/src/telemetry/userConfig';45import { INotebookDocument, ITextDocument, TextDocumentIdentifier } from '../../extension/completions-core/vscode-node/lib/src/textDocument';46import { ICompletionsTextDocumentManagerService, TextDocumentChangeEvent, TextDocumentCloseEvent, TextDocumentFocusedEvent, TextDocumentManager, TextDocumentOpenEvent, WorkspaceFoldersChangeEvent } from '../../extension/completions-core/vscode-node/lib/src/textDocumentManager';47import { Event } from '../../extension/completions-core/vscode-node/lib/src/util/event';48import { ICompletionsPromiseQueueService, PromiseQueue } from '../../extension/completions-core/vscode-node/lib/src/util/promiseQueue';49import { ICompletionsRuntimeModeService, RuntimeMode } from '../../extension/completions-core/vscode-node/lib/src/util/runtimeMode';50import { DocumentContext, WorkspaceFolder } from '../../extension/completions-core/vscode-node/types/src';51import { DebugRecorder } from '../../extension/inlineEdits/node/debugRecorder';52import { INextEditProvider, NESInlineCompletionContext, NextEditProvider } from '../../extension/inlineEdits/node/nextEditProvider';53import { LlmNESTelemetryBuilder, NextEditProviderTelemetryBuilder, TelemetrySender } from '../../extension/inlineEdits/node/nextEditProviderTelemetry';54import { INextEditResult } from '../../extension/inlineEdits/node/nextEditResult';55import { IPowerService, NullPowerService } from '../../extension/power/common/powerService';56import { ChatMLFetcherImpl } from '../../extension/prompt/node/chatMLFetcher';57import { ISimilarFilesContextService, NullSimilarFilesContextService } from '../../extension/xtab/common/similarFilesContextService';58import { XtabProvider } from '../../extension/xtab/node/xtabProvider';59import { IAuthenticationService } from '../../platform/authentication/common/authentication';60import { ICopilotTokenManager } from '../../platform/authentication/common/copilotTokenManager';61import { CopilotTokenStore, ICopilotTokenStore } from '../../platform/authentication/common/copilotTokenStore';62import { StaticGitHubAuthenticationService } from '../../platform/authentication/common/staticGitHubAuthenticationService';63import { createStaticGitHubTokenProvider } from '../../platform/authentication/node/copilotTokenManager';64import { IChatMLFetcher } from '../../platform/chat/common/chatMLFetcher';65import { IChatQuotaService } from '../../platform/chat/common/chatQuotaService';66import { ChatQuotaService } from '../../platform/chat/common/chatQuotaServiceImpl';67import { IConversationOptions } from '../../platform/chat/common/conversationOptions';68import { IInteractionService, InteractionService } from '../../platform/chat/common/interactionService';69import { BaseConfig, Config, ConfigKey, CopilotConfigPrefix, ExperimentBasedConfig, ExperimentBasedConfigType, globalConfigRegistry, IConfigurationService } from '../../platform/configuration/common/configurationService';70import { DefaultsOnlyConfigurationService } from '../../platform/configuration/common/defaultsOnlyConfigurationService';71import { IDiffService } from '../../platform/diff/common/diffService';72import { DiffServiceImpl } from '../../platform/diff/node/diffServiceImpl';73import { ICAPIClientService } from '../../platform/endpoint/common/capiClient';74import { IDomainService } from '../../platform/endpoint/common/domainService';75import { IEndpointProvider } from '../../platform/endpoint/common/endpointProvider';76import { CAPIClientImpl } from '../../platform/endpoint/node/capiClientImpl';77import { DomainService } from '../../platform/endpoint/node/domainServiceImpl';78import { IEnvService, NameAndVersion, OperatingSystem } from '../../platform/env/common/envService';79import { NullEnvService } from '../../platform/env/common/nullEnvService';80import { IGitExtensionService } from '../../platform/git/common/gitExtensionService';81import { NullGitExtensionService } from '../../platform/git/common/nullGitExtensionService';82import { IIgnoreService, NullIgnoreService } from '../../platform/ignore/common/ignoreService';83import { DocumentId } from '../../platform/inlineEdits/common/dataTypes/documentId';84import { InlineEditRequestLogContext } from '../../platform/inlineEdits/common/inlineEditLogContext';85import { IInlineEditsModelService, IUndesiredModelsManager, NullUndesiredModelsManager } from '../../platform/inlineEdits/common/inlineEditsModelService';86import { ObservableGit } from '../../platform/inlineEdits/common/observableGit';87import { IObservableDocument, ObservableWorkspace } from '../../platform/inlineEdits/common/observableWorkspace';88import { NesHistoryContextProvider } from '../../platform/inlineEdits/common/workspaceEditTracker/nesHistoryContextProvider';89import { NesXtabHistoryTracker } from '../../platform/inlineEdits/common/workspaceEditTracker/nesXtabHistoryTracker';90import { InlineEditsModelService } from '../../platform/inlineEdits/node/inlineEditsModelService';91import { ILanguageContextProviderService } from '../../platform/languageContextProvider/common/languageContextProviderService';92import { NullLanguageContextProviderService } from '../../platform/languageContextProvider/common/nullLanguageContextProviderService';93import { ILanguageDiagnosticsService } from '../../platform/languages/common/languageDiagnosticsService';94import { TestLanguageDiagnosticsService } from '../../platform/languages/common/testLanguageDiagnosticsService';95import { ConsoleLog, ILogService, LogLevel as InternalLogLevel, LogServiceImpl } from '../../platform/log/common/logService';96import { ICompletionsFetchService } from '../../platform/nesFetch/common/completionsFetchService';97import { CompletionsFetchService } from '../../platform/nesFetch/node/completionsFetchServiceImpl';98import { FetchOptions, HeadersImpl, IAbortController, IFetcherService, PaginationOptions, WebSocketConnection, WebSocketConnectOptions } from '../../platform/networking/common/fetcherService';99import { IFetcher } from '../../platform/networking/common/networking';100import { IChatWebSocketManager, NullChatWebSocketManager } from '../../platform/networking/node/chatWebSocketManager';101import { NoopOTelService } from '../../platform/otel/common/noopOtelService';102import { resolveOTelConfig } from '../../platform/otel/common/otelConfig';103import { IOTelService } from '../../platform/otel/common/otelService';104import { IProxyModelsService } from '../../platform/proxyModels/common/proxyModelsService';105import { ProxyModelsService } from '../../platform/proxyModels/node/proxyModelsService';106import { IRequestLogger } from '../../platform/requestLogger/common/requestLogger';107import { NullRequestLogger } from '../../platform/requestLogger/node/nullRequestLogger';108import { ISimulationTestContext, NulSimulationTestContext } from '../../platform/simulationTestContext/common/simulationTestContext';109import { ISnippyService, NullSnippyService } from '../../platform/snippy/common/snippyService';110import { IExperimentationService, TreatmentsChangeEvent } from '../../platform/telemetry/common/nullExperimentationService';111import { ITelemetryService, TelemetryDestination, TelemetryEventMeasurements, TelemetryEventProperties } from '../../platform/telemetry/common/telemetry';112import { eventPropertiesToSimpleObject } from '../../platform/telemetry/common/telemetryData';113import { unwrapEventNameFromPrefix } from '../../platform/telemetry/node/azureInsightsReporter';114import { ITerminalService, NullTerminalService } from '../../platform/terminal/common/terminalService';115import { ITokenizerProvider, TokenizerProvider } from '../../platform/tokenizer/node/tokenizer';116import { IWorkspaceService, NullWorkspaceService } from '../../platform/workspace/common/workspaceService';117import { InstantiationServiceBuilder } from '../../util/common/services';118import { CancellationToken } from '../../util/vs/base/common/cancellation';119import { Emitter, Event as VsEvent } from '../../util/vs/base/common/event';120import { Disposable, IDisposable } from '../../util/vs/base/common/lifecycle';121import { IObservableWithChange } from '../../util/vs/base/common/observableInternal';122import { URI } from '../../util/vs/base/common/uri';123import { generateUuid } from '../../util/vs/base/common/uuid';124import { SyncDescriptor } from '../../util/vs/platform/instantiation/common/descriptors';125import { IInstantiationService } from '../../util/vs/platform/instantiation/common/instantiation';126export {127IAuthenticationService, ICAPIClientService, IEndpointProvider, IExperimentationService, IIgnoreService, ILanguageContextProviderService128};129130/**131* Log levels (taken from vscode.d.ts)132*/133export enum LogLevel {134135/**136* No messages are logged with this level.137*/138Off = 0,139140/**141* All messages are logged with this level.142*/143Trace = 1,144145/**146* Messages with debug and higher log level are logged with this level.147*/148Debug = 2,149150/**151* Messages with info and higher log level are logged with this level.152*/153Info = 3,154155/**156* Messages with warning and higher log level are logged with this level.157*/158Warning = 4,159160/**161* Only error messages are logged with this level.162*/163Error = 5164}165166export interface ILogTarget {167logIt(level: LogLevel, metadataStr: string, ...extra: any[]): void;168show?(preserveFocus?: boolean): void;169}170171export interface ITelemetrySender {172sendTelemetryEvent(eventName: string, properties?: Record<string, string | undefined>, measurements?: Record<string, number | undefined>): void;173sendEnhancedTelemetryEvent?(eventName: string, properties?: Record<string, string | undefined>, measurements?: Record<string, number | undefined>): void;174}175176export interface INESProviderOptions {177readonly workspace: ObservableWorkspace;178readonly fetcher: IFetcher;179readonly copilotTokenManager: ICopilotTokenManager;180readonly terminalService: ITerminalService;181readonly telemetrySender: ITelemetrySender;182readonly logTarget?: ILogTarget;183/**184* If true, the provider will wait for treatment variables to be set.185* INESProvider.updateTreatmentVariables() must be called to unblock.186*/187readonly waitForTreatmentVariables?: boolean;188readonly undesiredModelsManager?: IUndesiredModelsManager;189readonly configOverrides?: Map<ConfigKeyType, unknown>;190}191192export interface INESResult {193readonly result?: {194readonly newText: string;195readonly range: {196readonly start: number;197readonly endExclusive: number;198};199};200}201202export interface INESProvider<T extends INESResult = INESResult> {203getId(): string;204getNextEdit(documentUri: vscode.Uri, cancellationToken: CancellationToken): Promise<T>;205handleShown(suggestion: T): void;206handleAcceptance(suggestion: T): void;207handleRejection(suggestion: T): void;208handleIgnored(suggestion: T, supersededByRequestUuid: T | undefined): void;209updateTreatmentVariables(variables: Record<string, boolean | number | string>): void;210setConfigs(overrides: Map<string, unknown>): Promise<void>;211dispose(): void;212}213214export function createNESProvider(options: INESProviderOptions): INESProvider<INESResult> {215const instantiationService = setupServices(options);216return instantiationService.createInstance(NESProvider, options);217}218219interface NESResult extends INESResult {220docId: DocumentId;221requestUuid: string;222internalResult: INextEditResult;223telemetryBuilder: NextEditProviderTelemetryBuilder;224}225226class NESProvider extends Disposable implements INESProvider<NESResult> {227private readonly _nextEditProvider: INextEditProvider<INextEditResult, LlmNESTelemetryBuilder>;228private readonly _telemetrySender: TelemetrySender;229private readonly _debugRecorder: DebugRecorder;230231constructor(232private _options: INESProviderOptions,233@IInstantiationService instantiationService: IInstantiationService,234@IExperimentationService private readonly _expService: IExperimentationService,235@IConfigurationService private readonly _configurationService: IConfigurationService,236@IWorkspaceService private readonly _workspaceService: IWorkspaceService,237) {238super();239const statelessNextEditProvider = instantiationService.createInstance(XtabProvider);240const git = instantiationService.createInstance(ObservableGit);241const historyContextProvider = new NesHistoryContextProvider(this._options.workspace, git);242const xtabDiffNEntries = this._configurationService.getExperimentBasedConfig(ConfigKey.TeamInternal.InlineEditsXtabDiffNEntries, this._expService);243const xtabHistoryTracker = new NesXtabHistoryTracker(this._options.workspace, xtabDiffNEntries, _configurationService, _expService);244this._debugRecorder = this._register(new DebugRecorder(this._options.workspace));245246this._nextEditProvider = instantiationService.createInstance(NextEditProvider, this._options.workspace, statelessNextEditProvider, historyContextProvider, xtabHistoryTracker, this._debugRecorder);247this._telemetrySender = this._register(instantiationService.createInstance(TelemetrySender, this._options.workspace));248}249250getId(): string {251return this._nextEditProvider.ID;252}253254handleShown(result: NESResult): void {255result.telemetryBuilder.setAsShown();256this._nextEditProvider.handleShown(result.internalResult);257}258259handleAcceptance(result: NESResult): void {260result.telemetryBuilder.setAcceptance('accepted');261result.telemetryBuilder.setStatus('accepted');262this._nextEditProvider.handleAcceptance(result.docId, result.internalResult);263this.handleEndOfLifetime(result);264}265266handleRejection(result: NESResult): void {267result.telemetryBuilder.setAcceptance('rejected');268result.telemetryBuilder.setStatus('rejected');269this._nextEditProvider.handleRejection(result.docId, result.internalResult);270this.handleEndOfLifetime(result);271}272273handleIgnored(result: NESResult, supersededByRequestUuid: NESResult | undefined): void {274if (supersededByRequestUuid) {275result.telemetryBuilder.setSupersededBy(supersededByRequestUuid.requestUuid);276}277this._nextEditProvider.handleIgnored(result.docId, result.internalResult, supersededByRequestUuid?.internalResult);278this.handleEndOfLifetime(result);279}280281private handleEndOfLifetime(result: NESResult): void {282try {283this._telemetrySender.sendTelemetryForBuilder(result.telemetryBuilder);284} finally {285result.telemetryBuilder.dispose();286}287}288289async getNextEdit(documentUri: vscode.Uri, cancellationToken: CancellationToken): Promise<NESResult> {290const docId = DocumentId.create(documentUri.toString());291292// Create minimal required context objects293const context: NESInlineCompletionContext = {294triggerKind: 1, // Invoke295selectedCompletionInfo: undefined,296requestUuid: generateUuid(),297requestIssuedDateTime: Date.now(),298earliestShownDateTime: Date.now() + 200,299enforceCacheDelay: true,300};301302// Create log context303const logContext = new InlineEditRequestLogContext(documentUri.toString(), 1, context);304305const document = this._options.workspace.getDocument(docId);306if (!document) {307throw new Error('DocumentNotFound');308}309310// Create telemetry builder - we'll need to pass null/undefined for services we don't have311const telemetryBuilder = new NextEditProviderTelemetryBuilder(312new NullGitExtensionService(),313undefined, // INotebookService314this._workspaceService,315this._nextEditProvider.ID,316document,317this._debugRecorder,318logContext.recordingBookmark319);320telemetryBuilder.setOpportunityId(context.requestUuid);321322try {323const internalResult = await this._nextEditProvider.getNextEdit(docId, context, logContext, cancellationToken, telemetryBuilder.nesBuilder);324const result: NESResult = {325result: internalResult.result?.edit ? {326newText: internalResult.result.edit.newText,327range: internalResult.result.edit.replaceRange,328} : undefined,329docId,330requestUuid: context.requestUuid,331internalResult,332telemetryBuilder,333};334return result;335} catch (e) {336try {337this._telemetrySender.sendTelemetryForBuilder(telemetryBuilder);338} finally {339telemetryBuilder.dispose();340}341throw e;342}343}344345updateTreatmentVariables(variables: Record<string, boolean | number | string>) {346if (this._expService instanceof SimpleExperimentationService) {347this._expService.updateTreatmentVariables(variables);348}349}350351async setConfigs(overrides: Map<string, unknown>) {352for (const [key, value] of overrides) {353const config = globalConfigRegistry.configs.get(`${CopilotConfigPrefix}.${key}`);354if (config) {355await this._configurationService.setConfig(config, value);356}357}358}359360}361362function setupServices(options: INESProviderOptions) {363const { fetcher, copilotTokenManager, telemetrySender, logTarget } = options;364const builder = new InstantiationServiceBuilder();365builder.define(IConfigurationService, new SyncDescriptor(OverridableConfigurationService, [options.configOverrides ?? new Map()]));366builder.define(IExperimentationService, new SyncDescriptor(SimpleExperimentationService, [options.waitForTreatmentVariables]));367builder.define(ISimulationTestContext, new SyncDescriptor(NulSimulationTestContext));368builder.define(IWorkspaceService, new SyncDescriptor(NullWorkspaceService));369builder.define(IDiffService, new SyncDescriptor(DiffServiceImpl, [false]));370builder.define(ILogService, new SyncDescriptor(LogServiceImpl, [[logTarget || new ConsoleLog(undefined, InternalLogLevel.Trace)]]));371builder.define(IGitExtensionService, new SyncDescriptor(NullGitExtensionService));372builder.define(ILanguageContextProviderService, new SyncDescriptor(NullLanguageContextProviderService));373builder.define(ILanguageDiagnosticsService, new SyncDescriptor(TestLanguageDiagnosticsService));374builder.define(IIgnoreService, new SyncDescriptor(NullIgnoreService));375builder.define(ISnippyService, new SyncDescriptor(NullSnippyService));376builder.define(IDomainService, new SyncDescriptor(DomainService));377builder.define(ICAPIClientService, new SyncDescriptor(CAPIClientImpl));378builder.define(ICopilotTokenStore, new SyncDescriptor(CopilotTokenStore));379builder.define(IEnvService, new SyncDescriptor(NullEnvService));380builder.define(IFetcherService, new SyncDescriptor(SingleFetcherService, [fetcher]));381builder.define(ITelemetryService, new SyncDescriptor(SimpleTelemetryService, [telemetrySender]));382builder.define(IAuthenticationService, new SyncDescriptor(StaticGitHubAuthenticationService, [createStaticGitHubTokenProvider()]));383builder.define(ICopilotTokenManager, copilotTokenManager);384builder.define(IPowerService, new SyncDescriptor(NullPowerService));385builder.define(IChatMLFetcher, new SyncDescriptor(ChatMLFetcherImpl));386builder.define(IChatWebSocketManager, new SyncDescriptor(NullChatWebSocketManager));387builder.define(IOTelService, new NoopOTelService(resolveOTelConfig({ env: {}, extensionVersion: '0.0.0', sessionId: 'chatlib' })));388builder.define(IChatQuotaService, new SyncDescriptor(ChatQuotaService));389builder.define(IInteractionService, new SyncDescriptor(InteractionService));390builder.define(IRequestLogger, new SyncDescriptor(NullRequestLogger));391builder.define(ITokenizerProvider, new SyncDescriptor(TokenizerProvider, [false]));392builder.define(IConversationOptions, {393_serviceBrand: undefined,394maxResponseTokens: undefined,395temperature: 0.1,396topP: 1,397rejectionMessage: 'Sorry, but I can only assist with programming related questions.',398});399builder.define(IProxyModelsService, new SyncDescriptor(ProxyModelsService));400builder.define(IInlineEditsModelService, new SyncDescriptor(InlineEditsModelService));401builder.define(IUndesiredModelsManager, options.undesiredModelsManager || new SyncDescriptor(NullUndesiredModelsManager));402builder.define(ITerminalService, options.terminalService || new SyncDescriptor(NullTerminalService));403builder.define(ISimilarFilesContextService, new SyncDescriptor(NullSimilarFilesContextService));404builder.define(IEndpointProvider, new NullEndpointProvider());405const configProvider = new InMemoryConfigProvider(new DefaultsOnlyConfigProvider());406if (options.configOverrides) {407configProvider.setOverrides(options.configOverrides);408}409builder.define(ICompletionsConfigProvider, configProvider);410return builder.seal();411}412413class OverridableConfigurationService extends DefaultsOnlyConfigurationService {414private _overrides: Map<string, unknown>;415416constructor(overrides: Map<string, unknown>) {417super();418this._overrides = overrides;419}420421override async setConfig<T>(key: BaseConfig<T>, value: T): Promise<void> {422const existing = this._overrides.get(key.id);423if (existing === value) {424return;425}426if (value === undefined) {427this._overrides.delete(key.id);428} else {429this._overrides.set(key.id, value);430}431const fullyQualifiedKey = key.fullyQualifiedId;432this._onDidChangeConfiguration.fire({433affectsConfiguration: (section) => {434return fullyQualifiedKey === section || fullyQualifiedKey.startsWith(section + '.') || section.startsWith(fullyQualifiedKey + '.');435}436});437return;438}439440override getConfig<T>(key: Config<T>): T {441if (this._overrides.has(key.id)) {442const overriddenValue = this._overrides.get(key.id);443if (key.validator) {444const result = key.validator.validate(overriddenValue);445if (result.error) {446return super.getConfig(key);447}448return result.content;449}450return overriddenValue as T;451}452return super.getConfig(key);453}454455override getExperimentBasedConfig<T extends ExperimentBasedConfigType>(key: ExperimentBasedConfig<T>, experimentationService: IExperimentationService): T {456if (this._overrides.has(key.id)) {457const overriddenValue = this._overrides.get(key.id);458if (key.validator) {459const result = key.validator.validate(overriddenValue);460if (result.error) {461return super.getExperimentBasedConfig(key, experimentationService);462}463return result.content;464}465return overriddenValue as T;466}467return super.getExperimentBasedConfig(key, experimentationService);468}469470override inspectConfig<T>(key: BaseConfig<T>) {471if (this._overrides.has(key.id)) {472const overriddenValue = this._overrides.get(key.id);473if (key.validator) {474const result = key.validator.validate(overriddenValue);475if (result.error) {476return super.inspectConfig(key);477}478return { defaultValue: result.content };479}480return { defaultValue: overriddenValue as T };481}482return super.inspectConfig(key);483}484}485486class NullEndpointProvider implements IEndpointProvider {487declare readonly _serviceBrand: undefined;488readonly onDidModelsRefresh = VsEvent.None;489async getAllCompletionModels(): Promise<[]> { return []; }490async getAllChatEndpoints(): Promise<[]> { return []; }491async getChatEndpoint(): Promise<never> { throw new Error('not implemented'); }492async getEmbeddingsEndpoint(): Promise<never> { throw new Error('not implemented'); }493}494495export class SimpleExperimentationService extends Disposable implements IExperimentationService {496497declare readonly _serviceBrand: undefined;498499private readonly variables: Record<string, boolean | number | string> = {};500private readonly _onDidTreatmentsChange = this._register(new Emitter<TreatmentsChangeEvent>());501readonly onDidTreatmentsChange = this._onDidTreatmentsChange.event;502503private readonly waitFor: Promise<void>;504private readonly resolveWaitFor: () => void;505506constructor(507waitForTreatmentVariables: boolean | undefined,508@IConfigurationService private readonly _configurationService: IConfigurationService,509) {510super();511if (waitForTreatmentVariables) {512let resolveWaitFor: () => void;513this.waitFor = new Promise<void>(resolve => {514resolveWaitFor = resolve;515});516this.resolveWaitFor = resolveWaitFor!;517} else {518this.waitFor = Promise.resolve();519this.resolveWaitFor = () => { };520}521}522523async hasTreatments(): Promise<void> {524return this.waitFor;525}526527getTreatmentVariable<T extends boolean | number | string>(name: string): T | undefined {528return this.variables[name] as T | undefined;529}530531async setCompletionsFilters(_filters: Map<string, string>): Promise<void> { }532533updateTreatmentVariables(variables: Record<string, boolean | number | string>): void {534const changedVariables: string[] = [];535for (const [key, value] of Object.entries(variables)) {536const existing = this.variables[key];537if (existing !== value) {538this.variables[key] = value;539changedVariables.push(key);540}541}542for (const key of Object.keys(this.variables)) {543if (!Object.hasOwn(variables, key)) {544delete this.variables[key];545changedVariables.push(key);546}547}548if (changedVariables.length > 0) {549this._onDidTreatmentsChange.fire({ affectedTreatmentVariables: changedVariables });550this._configurationService.updateExperimentBasedConfiguration(changedVariables);551}552this.resolveWaitFor();553}554}555556class SingleFetcherService implements IFetcherService {557558declare readonly _serviceBrand: undefined;559readonly onDidFetch = VsEvent.None;560readonly onDidCompleteFetch = VsEvent.None;561562constructor(563private readonly _fetcher: IFetcher,564) { }565566fetchWithPagination<T>(baseUrl: string, options: PaginationOptions<T>): Promise<T[]> {567return this._fetcher.fetchWithPagination(baseUrl, options);568}569570getUserAgentLibrary(): string {571return this._fetcher.getUserAgentLibrary();572}573574fetch(url: string, options: FetchOptions) {575return this._fetcher.fetch(url, options);576}577createWebSocket(url: string, options?: WebSocketConnectOptions): WebSocketConnection {578return { webSocket: new WebSocket(url, options), responseHeaders: new HeadersImpl({}), responseStatusCode: undefined, responseStatusText: undefined, networkError: undefined };579}580disconnectAll(): Promise<unknown> {581return this._fetcher.disconnectAll();582}583makeAbortController(): IAbortController {584return this._fetcher.makeAbortController();585}586isAbortError(e: any): boolean {587return this._fetcher.isAbortError(e);588}589isInternetDisconnectedError(e: any): boolean {590return this._fetcher.isInternetDisconnectedError(e);591}592isFetcherError(e: any): boolean {593return this._fetcher.isFetcherError(e);594}595isNetworkProcessCrashedError(e: any): boolean {596return this._fetcher.isNetworkProcessCrashedError(e);597}598getUserMessageForFetcherError(err: any): string {599return this._fetcher.getUserMessageForFetcherError(err);600}601}602603class SimpleTelemetryService implements ITelemetryService {604declare readonly _serviceBrand: undefined;605606constructor(private readonly _telemetrySender: ITelemetrySender) { }607608dispose(): void {609return;610}611612sendInternalMSFTTelemetryEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {613return;614}615sendMSFTTelemetryEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {616return;617}618sendMSFTTelemetryErrorEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {619return;620}621sendGHTelemetryEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {622this._telemetrySender.sendTelemetryEvent(eventName, eventPropertiesToSimpleObject(properties), measurements);623}624sendGHTelemetryErrorEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {625return;626}627sendGHTelemetryException(maybeError: unknown, origin: string): void {628return;629}630sendTelemetryEvent(eventName: string, destination: TelemetryDestination, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {631return;632}633sendTelemetryErrorEvent(eventName: string, destination: TelemetryDestination, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {634return;635}636setSharedProperty(name: string, value: string): void {637return;638}639setAdditionalExpAssignments(expAssignments: string[]): void {640return;641}642postEvent(eventName: string, props: Map<string, string>): void {643return;644}645646sendEnhancedGHTelemetryEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {647if (this._telemetrySender.sendEnhancedTelemetryEvent) {648this._telemetrySender.sendEnhancedTelemetryEvent(eventName, eventPropertiesToSimpleObject(properties), measurements);649}650}651sendEnhancedGHTelemetryErrorEvent(eventName: string, properties?: TelemetryEventProperties | undefined, measurements?: TelemetryEventMeasurements | undefined): void {652return;653}654}655656export type IDocumentContext = DocumentContext;657658export type CompletionsContextProviderMatchFunction = (documentSelector: DocumentSelector, documentContext: IDocumentContext) => Promise<number>;659660export type ICompletionsStatusChangedEvent = StatusChangedEvent;661662export interface ICompletionsStatusHandler {663didChange(event: ICompletionsStatusChangedEvent): void;664}665666export type ICompletionsTextDocumentChangeEvent = Event<TextDocumentChangeEvent>;667export type ICompletionsTextDocumentOpenEvent = Event<TextDocumentOpenEvent>;668export type ICompletionsTextDocumentCloseEvent = Event<TextDocumentCloseEvent>;669export type ICompletionsTextDocumentFocusedEvent = Event<TextDocumentFocusedEvent>;670export type ICompletionsWorkspaceFoldersChangeEvent = Event<WorkspaceFoldersChangeEvent>;671export type ICompletionsTextDocumentIdentifier = TextDocumentIdentifier;672export type ICompletionsNotebookDocument = INotebookDocument;673export type ICompletionsWorkspaceFolder = WorkspaceFolder;674675export interface ICompletionsTextDocumentManager {676onDidChangeTextDocument: ICompletionsTextDocumentChangeEvent;677onDidOpenTextDocument: ICompletionsTextDocumentOpenEvent;678onDidCloseTextDocument: ICompletionsTextDocumentCloseEvent;679680onDidFocusTextDocument: ICompletionsTextDocumentFocusedEvent;681onDidChangeWorkspaceFolders: ICompletionsWorkspaceFoldersChangeEvent;682683/**684* Get all open text documents, skipping content exclusions and other validations.685*/686getTextDocumentsUnsafe(): ITextDocument[];687688/**689* If `TextDocument` represents notebook returns `INotebookDocument` instance, otherwise returns `undefined`690*/691findNotebook(doc: TextDocumentIdentifier): ICompletionsNotebookDocument | undefined;692693getWorkspaceFolders(): WorkspaceFolder[];694}695696export interface IURLOpener {697open(url: string): Promise<void>;698}699700export type IEditorInfo = EditorInfo;701export type IEditorPluginInfo = EditorPluginInfo;702703export interface IEditorSession {704readonly sessionId: string;705readonly machineId: string;706readonly remoteName?: string;707readonly uiKind?: string;708}709710export type IActionItem = ActionItem;711export interface INotificationSender {712showWarningMessage(message: string, ...actions: IActionItem[]): Promise<IActionItem | undefined>;713}714715export type IIPCitationDetail = IPCitationDetail;716export type IIPDocumentCitation = IPDocumentCitation;717export interface IInlineCompletionsCitationHandler {718handleIPCodeCitation(citation: IIPDocumentCitation): Promise<void>;719}720721722export interface IInlineCompletionsProviderOptions {723readonly fetcher: IFetcher;724readonly authService: IAuthenticationService;725readonly telemetrySender: ITelemetrySender;726readonly logTarget?: ILogTarget;727readonly isRunningInTest?: boolean;728readonly contextProviderMatch: CompletionsContextProviderMatchFunction;729readonly languageContextProvider?: ILanguageContextProviderService;730readonly statusHandler: ICompletionsStatusHandler;731readonly documentManager: ICompletionsTextDocumentManager;732readonly workspace: ObservableWorkspace;733readonly urlOpener: IURLOpener;734readonly editorInfo: IEditorInfo;735readonly editorPluginInfo: IEditorPluginInfo;736readonly relatedPluginInfo: IEditorPluginInfo[];737readonly editorSession: IEditorSession;738readonly notificationSender: INotificationSender;739readonly ignoreService?: IIgnoreService;740readonly waitForTreatmentVariables?: boolean;741readonly endpointProvider: IEndpointProvider;742readonly capiClientService?: ICAPIClientService;743readonly citationHandler?: IInlineCompletionsCitationHandler;744readonly configOverrides?: Map<ConfigKeyType, unknown>;745}746747export type IGetInlineCompletionsOptions = Exclude<Partial<GetGhostTextOptions>, 'promptOnly'> & {748formattingOptions?: ITextEditorOptions;749};750751export interface IInlineCompletionsProvider {752updateTreatmentVariables(variables: Record<string, boolean | number | string>): void;753setConfigs(overrides: Map<string, unknown>): Promise<void>;754getInlineCompletions(textDocument: ITextDocument, position: Position, token?: CancellationToken, options?: IGetInlineCompletionsOptions): Promise<CopilotCompletion[] | undefined>;755inlineCompletionShown(completionId: string): Promise<void>;756dispose(): void;757}758759export function createInlineCompletionsProvider(options: IInlineCompletionsProviderOptions): IInlineCompletionsProvider {760const svc = setupCompletionServices(options);761return svc.createInstance(InlineCompletionsProvider);762}763764class InlineCompletionsProvider extends Disposable implements IInlineCompletionsProvider {765766private readonly ghostText: GhostText;767768constructor(769@IInstantiationService private _insta: IInstantiationService,770@IExperimentationService private readonly _expService: IExperimentationService,771@ICompletionsSpeculativeRequestCache private readonly _speculativeRequestCache: ICompletionsSpeculativeRequestCache,772@ILogService private readonly _logService: ILogService,773@IConfigurationService private readonly _configurationService: IConfigurationService,774@ICompletionsConfigProvider private readonly _completionsConfigProvider: ICompletionsConfigProvider,775) {776super();777this._register(_insta);778this.ghostText = this._insta.createInstance(GhostText);779}780781updateTreatmentVariables(variables: Record<string, boolean | number | string>) {782if (this._expService instanceof SimpleExperimentationService) {783this._expService.updateTreatmentVariables(variables);784}785}786787async setConfigs(overrides: Map<string, unknown>) {788for (const [key, value] of overrides) {789const config = globalConfigRegistry.configs.get(`${CopilotConfigPrefix}.${key}`);790if (config) {791await this._configurationService.setConfig(config, value);792}793}794if (this._completionsConfigProvider instanceof InMemoryConfigProvider) {795this._completionsConfigProvider.setCopilotSettings(Object.fromEntries(overrides));796}797}798799async getInlineCompletions(textDocument: ITextDocument, position: Position, token?: CancellationToken, options?: IGetInlineCompletionsOptions): Promise<CopilotCompletion[] | undefined> {800const telemetryBuilder = new LlmNESTelemetryBuilder(undefined, undefined, undefined, 'ghostText', undefined);801return await this.ghostText.getInlineCompletions(textDocument, position, token ?? CancellationToken.None, options, new GhostTextLogContext(textDocument.uri, textDocument.version, undefined), telemetryBuilder, this._logService);802}803804async inlineCompletionShown(completionId: string): Promise<void> {805return await this._speculativeRequestCache.request(completionId);806}807}808809class UnwrappingTelemetrySender implements ITelemetrySender {810constructor(private readonly sender: ITelemetrySender) { }811812sendTelemetryEvent(eventName: string, properties?: Record<string, string | undefined>, measurements?: Record<string, number | undefined>): void {813this.sender.sendTelemetryEvent(this.normalizeEventName(eventName), properties, measurements);814}815816sendEnhancedTelemetryEvent(eventName: string, properties?: Record<string, string | undefined>, measurements?: Record<string, number | undefined>): void {817if (this.sender.sendEnhancedTelemetryEvent) {818this.sender.sendEnhancedTelemetryEvent(this.normalizeEventName(eventName), properties, measurements);819}820}821822private normalizeEventName(eventName: string): string {823const unwrapped = unwrapEventNameFromPrefix(eventName);824const withoutPrefix = unwrapped.match(/^[^/]+\/(.*)/);825return withoutPrefix ? withoutPrefix[1] : unwrapped;826}827}828829function setupCompletionServices(options: IInlineCompletionsProviderOptions): IInstantiationService {830const { fetcher, authService, statusHandler, documentManager, workspace, telemetrySender, urlOpener, editorSession } = options;831const logTarget = options.logTarget || new ConsoleLog(undefined, InternalLogLevel.Trace);832833const builder = new InstantiationServiceBuilder();834builder.define(ICompletionsLogTargetService, new class implements ICompletionsLogTargetService {835declare _serviceBrand: undefined;836logIt(level: CompletionsLogLevel, category: string, ...extra: unknown[]): void {837logTarget.logIt(this.toExternalLogLevel(level), category, ...extra);838}839private toExternalLogLevel(level: CompletionsLogLevel): LogLevel {840switch (level) {841case CompletionsLogLevel.DEBUG: return LogLevel.Debug;842case CompletionsLogLevel.INFO: return LogLevel.Info;843case CompletionsLogLevel.WARN: return LogLevel.Warning;844case CompletionsLogLevel.ERROR: return LogLevel.Error;845default: return LogLevel.Info;846}847}848});849builder.define(IAuthenticationService, authService);850builder.define(ILogService, new SyncDescriptor(LogServiceImpl, [[logTarget || new ConsoleLog(undefined, InternalLogLevel.Trace)]]));851builder.define(IIgnoreService, options.ignoreService || new NullIgnoreService());852builder.define(ITelemetryService, new SyncDescriptor(SimpleTelemetryService, [new UnwrappingTelemetrySender(telemetrySender)]));853builder.define(IConfigurationService, new SyncDescriptor(OverridableConfigurationService, [options.configOverrides ?? new Map()]));854builder.define(IExperimentationService, new SyncDescriptor(SimpleExperimentationService, [options.waitForTreatmentVariables]));855builder.define(IEndpointProvider, options.endpointProvider);856builder.define(ICAPIClientService, options.capiClientService || new SyncDescriptor(CAPIClientImpl));857builder.define(IFetcherService, new SyncDescriptor(SingleFetcherService, [fetcher]));858builder.define(ICompletionsTelemetryService, new SyncDescriptor(CompletionsTelemetryServiceBridge));859builder.define(ICompletionsRuntimeModeService, RuntimeMode.fromEnvironment(options.isRunningInTest ?? false));860builder.define(ICompletionsCacheService, new CompletionsCache());861const configProvider = new InMemoryConfigProvider(new DefaultsOnlyConfigProvider());862if (options.configOverrides) {863configProvider.setOverrides(options.configOverrides);864}865builder.define(ICompletionsConfigProvider, configProvider);866builder.define(ICompletionsLastGhostText, new LastGhostText());867builder.define(ICompletionsCurrentGhostText, new CurrentGhostText());868builder.define(ICompletionsSpeculativeRequestCache, new SpeculativeRequestCache());869builder.define(ICompletionsNotificationSender, new class implements ICompletionsNotificationSender {870declare _serviceBrand: undefined;871async showWarningMessage(message: string, ...actions: IActionItem[]): Promise<IActionItem | undefined> {872return await options.notificationSender.showWarningMessage(message, ...actions);873}874});875builder.define(ICompletionsEditorAndPluginInfo, new class implements ICompletionsEditorAndPluginInfo {876declare _serviceBrand: undefined;877getEditorInfo(): EditorInfo {878return options.editorInfo;879}880getEditorPluginInfo(): EditorPluginInfo {881return options.editorPluginInfo;882}883getRelatedPluginInfo(): EditorPluginInfo[] {884return options.relatedPluginInfo;885}886});887builder.define(ICompletionsExtensionStatus, new CopilotExtensionStatus());888builder.define(ICompletionsFeaturesService, new SyncDescriptor(Features));889builder.define(ICompletionsObservableWorkspace, new class implements ICompletionsObservableWorkspace {890declare _serviceBrand: undefined;891get openDocuments(): IObservableWithChange<readonly IObservableDocument[], { added: readonly IObservableDocument[]; removed: readonly IObservableDocument[] }> {892return workspace.openDocuments;893}894getWorkspaceRoot(documentId: DocumentId): URI | undefined {895return workspace.getWorkspaceRoot(documentId);896}897getFirstOpenDocument(): IObservableDocument | undefined {898return workspace.getFirstOpenDocument();899}900getDocument(documentId: DocumentId): IObservableDocument | undefined {901return workspace.getDocument(documentId);902}903});904builder.define(ICompletionsStatusReporter, new class extends StatusReporter {905didChange(event: StatusChangedEvent): void {906statusHandler.didChange(event);907}908});909builder.define(ICompletionsCopilotTokenManager, new SyncDescriptor(CopilotTokenManagerImpl, [false]));910builder.define(ICompletionsTextDocumentManagerService, new SyncDescriptor(class extends TextDocumentManager {911onDidChangeTextDocument = documentManager.onDidChangeTextDocument;912onDidOpenTextDocument = documentManager.onDidOpenTextDocument;913onDidCloseTextDocument = documentManager.onDidCloseTextDocument;914onDidFocusTextDocument = documentManager.onDidFocusTextDocument;915onDidChangeWorkspaceFolders = documentManager.onDidChangeWorkspaceFolders;916getTextDocumentsUnsafe(): ITextDocument[] {917return documentManager.getTextDocumentsUnsafe();918}919findNotebook(doc: TextDocumentIdentifier): INotebookDocument | undefined {920return documentManager.findNotebook(doc);921}922getWorkspaceFolders(): WorkspaceFolder[] {923return documentManager.getWorkspaceFolders();924}925}));926builder.define(ICompletionsFileReaderService, new SyncDescriptor(FileReader));927builder.define(ICompletionsBlockModeConfig, new SyncDescriptor(ConfigBlockModeConfig));928builder.define(ICompletionsTelemetryUserConfigService, new SyncDescriptor(TelemetryUserConfig));929builder.define(ICompletionsRecentEditsProviderService, new SyncDescriptor(FullRecentEditsProvider, [undefined]));930builder.define(ICompletionsNotifierService, new SyncDescriptor(CompletionNotifier));931builder.define(ICompletionsOpenAIFetcherService, new SyncDescriptor(LiveOpenAIFetcher));932builder.define(ICompletionsFetchService, new SyncDescriptor(CompletionsFetchService));933builder.define(ICompletionsModelManagerService, new SyncDescriptor(AvailableModelsManager, [true]));934builder.define(ICompletionsAsyncManagerService, new SyncDescriptor(AsyncCompletionManager));935builder.define(ICompletionsContextProviderBridgeService, new SyncDescriptor(ContextProviderBridge));936builder.define(ICompletionsUserErrorNotifierService, new SyncDescriptor(UserErrorNotifier));937builder.define(ICompletionsRelatedFilesProviderService, new SyncDescriptor(CompositeRelatedFilesProvider));938builder.define(ICompletionsFileSystemService, new LocalFileSystem());939builder.define(ICompletionsContextProviderRegistryService, new SyncDescriptor(CachedContextProviderRegistry, [CoreContextProviderRegistry, (_: IInstantiationService, sel: DocumentSelector, docCtx: DocumentContext) => options.contextProviderMatch(sel, docCtx)]));940builder.define(ICompletionsPromiseQueueService, new PromiseQueue());941builder.define(ICompletionsCitationManager, new class implements ICompletionsCitationManager {942declare _serviceBrand: undefined;943register(): IDisposable { return Disposable.None; }944async handleIPCodeCitation(citation: IPDocumentCitation): Promise<void> {945if (options.citationHandler) {946return await options.citationHandler.handleIPCodeCitation(citation);947}948}949});950builder.define(ICompletionsContextProviderService, new ContextProviderStatistics());951builder.define(ICompletionsPromptFactoryService, new SyncDescriptor(CompletionsPromptFactory));952builder.define(ICompletionsFetcherService, new class implements ICompletionsFetcherService {953declare _serviceBrand: undefined;954getImplementation(): ICompletionsFetcherService | Promise<ICompletionsFetcherService> {955return this;956}957fetch(url: string, options: FetchOptions) {958return fetcher.fetch(url, options);959}960disconnectAll(): Promise<unknown> {961return fetcher.disconnectAll();962}963});964builder.define(ICompletionsDefaultContextProviders, new DefaultContextProvidersContainer());965builder.define(IEnvService, new class implements IEnvService {966declare _serviceBrand: undefined;967readonly language = undefined;968readonly sessionId = editorSession.sessionId;969readonly machineId = editorSession.machineId;970readonly devDeviceId = editorSession.machineId;971readonly vscodeVersion = options.editorInfo.version;972readonly isActive = true;973readonly onDidChangeWindowState: vscode.Event<vscode.WindowState> = VsEvent.None;974readonly remoteName = editorSession.remoteName;975readonly uiKind = editorSession.uiKind === 'web' ? 'web' : 'desktop';976readonly OS = process.platform === 'darwin' ? OperatingSystem.Macintosh : process.platform === 'win32' ? OperatingSystem.Windows : OperatingSystem.Linux;977readonly uriScheme = '';978readonly extensionId = options.editorPluginInfo.name;979readonly appRoot = options.editorInfo.root ?? '';980readonly shell = '';981isProduction(): boolean { return BuildInfo.isProduction(); }982isPreRelease(): boolean { return BuildInfo.isPreRelease(); }983isSimulation(): boolean { return options.isRunningInTest === true; }984getBuildType(): 'prod' | 'dev' {985const t = BuildInfo.getBuildType();986return t === BuildType.DEV ? 'dev' : 'prod';987}988getVersion(): string { return BuildInfo.getVersion(); }989getBuild(): string { return BuildInfo.getBuild(); }990getName(): string { return options.editorInfo.name; }991getEditorInfo(): NameAndVersion { return new NameAndVersion(options.editorInfo.name, options.editorInfo.version); }992getEditorPluginInfo(): NameAndVersion { return new NameAndVersion(options.editorPluginInfo.name, options.editorPluginInfo.version); }993async openExternal(target: URI): Promise<boolean> {994await urlOpener.open(target.toString());995return true;996}997});998builder.define(ILanguageContextProviderService, options.languageContextProvider ?? new NullLanguageContextProviderService());999builder.define(ILanguageDiagnosticsService, new SyncDescriptor(TestLanguageDiagnosticsService));1000builder.define(IRequestLogger, new SyncDescriptor(NullRequestLogger));10011002return builder.seal();1003}100410051006