From afcd03463bb1439d08cd9dd8d506fabbf6b80bca Mon Sep 17 00:00:00 2001 From: Andrea Mah Date: Mon, 6 Apr 2026 15:57:36 -0700 Subject: [PATCH 1/2] Add support for chat-lib to setConfigs mid-runtime --- src/lib/node/chatLibMain.ts | 47 ++++++++++++++++++- .../defaultsOnlyConfigurationService.ts | 2 +- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/lib/node/chatLibMain.ts b/src/lib/node/chatLibMain.ts index 282f3ee98a..04f09f319e 100644 --- a/src/lib/node/chatLibMain.ts +++ b/src/lib/node/chatLibMain.ts @@ -67,7 +67,7 @@ import { IChatQuotaService } from '../../platform/chat/common/chatQuotaService'; import { ChatQuotaService } from '../../platform/chat/common/chatQuotaServiceImpl'; import { IConversationOptions } from '../../platform/chat/common/conversationOptions'; import { IInteractionService, InteractionService } from '../../platform/chat/common/interactionService'; -import { BaseConfig, Config, ConfigKey, ExperimentBasedConfig, ExperimentBasedConfigType, IConfigurationService } from '../../platform/configuration/common/configurationService'; +import { BaseConfig, Config, ConfigKey, CopilotConfigPrefix, ExperimentBasedConfig, ExperimentBasedConfigType, globalConfigRegistry, IConfigurationService } from '../../platform/configuration/common/configurationService'; import { DefaultsOnlyConfigurationService } from '../../platform/configuration/common/defaultsOnlyConfigurationService'; import { IDiffService } from '../../platform/diff/common/diffService'; import { DiffServiceImpl } from '../../platform/diff/node/diffServiceImpl'; @@ -208,6 +208,7 @@ export interface INESProvider { handleRejection(suggestion: T): void; handleIgnored(suggestion: T, supersededByRequestUuid: T | undefined): void; updateTreatmentVariables(variables: Record): void; + setConfigs(overrides: Map): void; dispose(): void; } @@ -348,6 +349,15 @@ class NESProvider extends Disposable implements INESProvider { } } + setConfigs(overrides: Map) { + for (const [key, value] of overrides) { + const config = globalConfigRegistry.configs.get(`${CopilotConfigPrefix}.${key}`); + if (config) { + this._configurationService.setConfig(config, value); + } + } + } + } function setupServices(options: INESProviderOptions) { @@ -402,8 +412,26 @@ function setupServices(options: INESProviderOptions) { } class OverridableConfigurationService extends DefaultsOnlyConfigurationService { - constructor(private readonly _overrides: Map) { + private _overrides: Map; + + constructor(overrides: Map) { super(); + this._overrides = overrides; + } + + override async setConfig(key: BaseConfig, value: T): Promise { + const existing = this._overrides.get(key.id); + if (existing === value) { + return; + } + this._overrides.set(key.id, value); + const fullyQualifiedKey = key.fullyQualifiedId; + this._onDidChangeConfiguration.fire({ + affectsConfiguration: (section) => { + return fullyQualifiedKey === section || fullyQualifiedKey.startsWith(section + '.') || section.startsWith(fullyQualifiedKey + '.'); + } + }); + return; } override getConfig(key: Config): T { @@ -727,6 +755,7 @@ export type IGetInlineCompletionsOptions = Exclude, export interface IInlineCompletionsProvider { updateTreatmentVariables(variables: Record): void; + setConfigs(overrides: Map): void; getInlineCompletions(textDocument: ITextDocument, position: Position, token?: CancellationToken, options?: IGetInlineCompletionsOptions): Promise; inlineCompletionShown(completionId: string): Promise; dispose(): void; @@ -746,6 +775,8 @@ class InlineCompletionsProvider extends Disposable implements IInlineCompletions @IExperimentationService private readonly _expService: IExperimentationService, @ICompletionsSpeculativeRequestCache private readonly _speculativeRequestCache: ICompletionsSpeculativeRequestCache, @ILogService private readonly _logService: ILogService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + @ICompletionsConfigProvider private readonly _completionsConfigProvider: ICompletionsConfigProvider, ) { super(); this._register(_insta); @@ -758,6 +789,18 @@ class InlineCompletionsProvider extends Disposable implements IInlineCompletions } } + setConfigs(overrides: Map) { + for (const [key, value] of overrides) { + const config = globalConfigRegistry.configs.get(`${CopilotConfigPrefix}.${key}`); + if (config) { + this._configurationService.setConfig(config, value); + } + } + if (this._completionsConfigProvider instanceof InMemoryConfigProvider) { + this._completionsConfigProvider.setCopilotSettings(Object.fromEntries(overrides)); + } + } + async getInlineCompletions(textDocument: ITextDocument, position: Position, token?: CancellationToken, options?: IGetInlineCompletionsOptions): Promise { const telemetryBuilder = new LlmNESTelemetryBuilder(undefined, undefined, undefined, 'ghostText', undefined); return await this.ghostText.getInlineCompletions(textDocument, position, token ?? CancellationToken.None, options, new GhostTextLogContext(textDocument.uri, textDocument.version, undefined), telemetryBuilder, this._logService); diff --git a/src/platform/configuration/common/defaultsOnlyConfigurationService.ts b/src/platform/configuration/common/defaultsOnlyConfigurationService.ts index d9c95ee433..489c9e5d73 100644 --- a/src/platform/configuration/common/defaultsOnlyConfigurationService.ts +++ b/src/platform/configuration/common/defaultsOnlyConfigurationService.ts @@ -21,7 +21,7 @@ export class DefaultsOnlyConfigurationService extends AbstractConfigurationServi }; } - override setConfig(): Promise { + override setConfig(key: BaseConfig, value: T): Promise { return Promise.resolve(); } From ac44981bdf2e771348466d828f8161f2ac078f90 Mon Sep 17 00:00:00 2001 From: Andrea Mah Date: Mon, 6 Apr 2026 19:25:58 -0700 Subject: [PATCH 2/2] copilot PR feedback --- src/lib/node/chatLibMain.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/node/chatLibMain.ts b/src/lib/node/chatLibMain.ts index 04f09f319e..51e01dbd78 100644 --- a/src/lib/node/chatLibMain.ts +++ b/src/lib/node/chatLibMain.ts @@ -424,7 +424,11 @@ class OverridableConfigurationService extends DefaultsOnlyConfigurationService { if (existing === value) { return; } - this._overrides.set(key.id, value); + if (value === undefined) { + this._overrides.delete(key.id); + } else { + this._overrides.set(key.id, value); + } const fullyQualifiedKey = key.fullyQualifiedId; this._onDidChangeConfiguration.fire({ affectsConfiguration: (section) => {