Skip to content

Commit 1c0caeb

Browse files
authored
Merge pull request microsoft#269558 from microsoft/benibenj/smoggy-ptarmigan
Send fewer telemetry events
2 parents df95260 + bf2f147 commit 1c0caeb

2 files changed

Lines changed: 58 additions & 4 deletions

File tree

src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ import { Disposable, DisposableStore, IDisposable, MutableDisposable, toDisposab
1212
import { derived, IObservable, IObservableWithChange, ITransaction, observableValue, recordChangesLazy, transaction } from '../../../../../base/common/observable.js';
1313
// eslint-disable-next-line local/code-no-deep-import-of-internal
1414
import { observableReducerSettable } from '../../../../../base/common/observableInternal/experimental/reducer.js';
15-
import { isDefined } from '../../../../../base/common/types.js';
15+
import { isDefined, isObject } from '../../../../../base/common/types.js';
1616
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
17+
import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';
1718
import { DataChannelForwardingTelemetryService, forwardToChannelIf, isCopilotLikeExtension } from '../../../../../platform/dataChannel/browser/forwardingTelemetryService.js';
1819
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
1920
import { ILogService } from '../../../../../platform/log/common/log.js';
2021
import { observableConfigValue } from '../../../../../platform/observable/common/platformObservableUtils.js';
22+
import product from '../../../../../platform/product/common/product.js';
2123
import { StringEdit } from '../../../../common/core/edits/stringEdit.js';
2224
import { Position } from '../../../../common/core/position.js';
2325
import { InlineCompletionEndOfLifeReasonKind, InlineCompletionTriggerKind, InlineCompletionsProvider } from '../../../../common/languages.js';
@@ -73,6 +75,8 @@ export class InlineCompletionsSource extends Disposable {
7375
public readonly inlineCompletions = this._state.map(this, v => v.inlineCompletions);
7476
public readonly suggestWidgetInlineCompletions = this._state.map(this, v => v.suggestWidgetInlineCompletions);
7577

78+
private _completionsEnabled: Record<string, boolean> | undefined = undefined;
79+
7680
constructor(
7781
private readonly _textModel: ITextModel,
7882
private readonly _versionId: IObservableWithChange<number | null, IModelContentChangedEvent | undefined>,
@@ -82,6 +86,7 @@ export class InlineCompletionsSource extends Disposable {
8286
@ILogService private readonly _logService: ILogService,
8387
@IConfigurationService private readonly _configurationService: IConfigurationService,
8488
@IInstantiationService private readonly _instantiationService: IInstantiationService,
89+
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
8590
) {
8691
super();
8792
this._loggingEnabled = observableConfigValue('editor.inlineSuggest.logFetch', false, this._configurationService).recomputeInitiallyAndOnChange(this._store);
@@ -94,6 +99,25 @@ export class InlineCompletionsSource extends Disposable {
9499
));
95100

96101
this.clearOperationOnTextModelChange.recomputeInitiallyAndOnChange(this._store);
102+
103+
const enablementSetting = product.defaultChatAgent?.completionsEnablementSetting ?? undefined;
104+
if (enablementSetting) {
105+
this._updateCompletionsEnablement(enablementSetting);
106+
this._register(this._configurationService.onDidChangeConfiguration(e => {
107+
if (e.affectsConfiguration(enablementSetting)) {
108+
this._updateCompletionsEnablement(enablementSetting);
109+
}
110+
}));
111+
}
112+
}
113+
114+
private _updateCompletionsEnablement(enalementSetting: string) {
115+
const result = this._configurationService.getValue<Record<string, boolean>>(enalementSetting);
116+
if (!isObject(result)) {
117+
this._completionsEnabled = undefined;
118+
} else {
119+
this._completionsEnabled = result;
120+
}
97121
}
98122

99123
public readonly clearOperationOnTextModelChange = derived(this, reader => {
@@ -260,7 +284,8 @@ export class InlineCompletionsSource extends Disposable {
260284
if (source.token.isCancellationRequested) {
261285
requestResponseInfo.setNoSuggestionReasonIfNotSet('canceled:whileFetching');
262286
} else {
263-
requestResponseInfo.setNoSuggestionReasonIfNotSet('noSuggestion');
287+
const completionsQuotaExceeded = this._contextKeyService.getContextKeyValue<boolean>('completionsQuotaExceeded');
288+
requestResponseInfo.setNoSuggestionReasonIfNotSet(completionsQuotaExceeded ? 'completionsQuotaExceeded' : 'noSuggestion');
264289
}
265290
}
266291

@@ -356,14 +381,23 @@ export class InlineCompletionsSource extends Disposable {
356381
private sendInlineCompletionsRequestTelemetry(
357382
requestResponseInfo: RequestResponseData
358383
): void {
359-
if (!this._sendRequestData.get()) {
384+
if (!this._sendRequestData.get() && !this._contextKeyService.getContextKeyValue<boolean>('isRunningUnificationExperiment')) {
360385
return;
361386
}
362387

363388
if (requestResponseInfo.requestUuid === undefined || requestResponseInfo.hasProducedSuggestion) {
364389
return;
365390
}
366391

392+
393+
if (!isCompletionsEnabled(this._completionsEnabled, this._textModel.getLanguageId())) {
394+
return;
395+
}
396+
397+
if (!requestResponseInfo.providers.some(p => isCopilotLikeExtension(p.providerId?.extensionId))) {
398+
return;
399+
}
400+
367401
const emptyEndOfLifeEvent: InlineCompletionEndOfLifeEvent = {
368402
id: requestResponseInfo.requestUuid,
369403
opportunityId: requestResponseInfo.requestUuid,
@@ -472,6 +506,18 @@ function isSubset<T>(set1: Set<T>, set2: Set<T>): boolean {
472506
return [...set1].every(item => set2.has(item));
473507
}
474508

509+
function isCompletionsEnabled(completionsEnablementObject: Record<string, boolean> | undefined, modeId: string = '*'): boolean {
510+
if (completionsEnablementObject === undefined) {
511+
return false; // default to disabled if setting is not available
512+
}
513+
514+
if (typeof completionsEnablementObject[modeId] !== 'undefined') {
515+
return Boolean(completionsEnablementObject[modeId]); // go with setting if explicitly defined
516+
}
517+
518+
return Boolean(completionsEnablementObject['*']); // fallback to global setting otherwise
519+
}
520+
475521
class UpdateOperation implements IDisposable {
476522
constructor(
477523
public readonly request: UpdateRequest,

src/vs/workbench/services/inlineCompletions/common/inlineCompletionsUnification.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { equals } from '../../../../base/common/arrays.js';
77
import { Event, Emitter } from '../../../../base/common/event.js';
88
import { Disposable } from '../../../../base/common/lifecycle.js';
9+
import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
910
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
1011
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
1112
import { IWorkbenchAssignmentService } from '../../assignment/common/assignmentService.js';
@@ -29,19 +30,25 @@ const CODE_UNIFICATION_PREFIX = 'cmp-cht-';
2930
const CODE_UNIFICATION_FF = 'inlineCompletionsUnificationCode';
3031
const MODEL_UNIFICATION_FF = 'inlineCompletionsUnificationModel';
3132

33+
export const isRunningUnificationExperiment = new RawContextKey<boolean>('isRunningUnificationExperiment', false);
34+
3235
export class InlineCompletionsUnificationImpl extends Disposable implements IInlineCompletionsUnificationService {
3336
readonly _serviceBrand: undefined;
3437

3538
private _state = new InlineCompletionsUnificationState(false, false, []);
3639
public get state(): IInlineCompletionsUnificationState { return this._state; }
3740

41+
private isRunningUnificationExperiment;
42+
3843
private readonly _onDidStateChange = this._register(new Emitter<void>());
3944
public readonly onDidStateChange = this._onDidStateChange.event;
4045

4146
constructor(
42-
@IWorkbenchAssignmentService private readonly _assignmentService: IWorkbenchAssignmentService
47+
@IWorkbenchAssignmentService private readonly _assignmentService: IWorkbenchAssignmentService,
48+
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
4349
) {
4450
super();
51+
this.isRunningUnificationExperiment = isRunningUnificationExperiment.bindTo(this._contextKeyService);
4552
this._register(this._assignmentService.onDidRefetchAssignments(() => this._update()));
4653
this._update();
4754
}
@@ -62,6 +69,7 @@ export class InlineCompletionsUnificationImpl extends Disposable implements IInl
6269
return;
6370
}
6471
this._state = newState;
72+
this.isRunningUnificationExperiment.set(this._state.codeUnification || this._state.modelUnification);
6573
this._onDidStateChange.fire();
6674
}
6775
}

0 commit comments

Comments
 (0)