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