From f25b6f9e0ca21b4324127d4ee2f798e734ea5cf2 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 30 Oct 2025 19:03:41 +0100 Subject: [PATCH 1/7] first cut - migrate settings marked with INTERNAL and adopt to advanced tag --- package.json | 417 ++++++++++++++++++ package.nls.json | 46 ++ .../vscode-node/configurationMigration.ts | 24 +- .../common/configurationService.ts | 130 ++++-- .../test/common/configurationService.spec.ts | 190 ++++---- 5 files changed, 631 insertions(+), 176 deletions(-) diff --git a/package.json b/package.json index 93d069bd21..90f21f753e 100644 --- a/package.json +++ b/package.json @@ -3160,6 +3160,423 @@ ] } } + }, + { + "id": "experimental", + "properties": { + "github.copilot.chat.debug.overrideChatEngine": { + "type": [ + "string", + "null" + ], + "markdownDescription": "%github.copilot.config.debug.overrideChatEngine%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.projectLabels.expanded": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.projectLabels.expanded%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.projectLabels.chat": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.projectLabels.chat%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.projectLabels.inline": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.projectLabels.inline%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.workspace.maxLocalIndexSize": { + "type": "number", + "default": 100000, + "markdownDescription": "%github.copilot.config.workspace.maxLocalIndexSize%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.workspace.enableFullWorkspace": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.workspace.enableFullWorkspace%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.workspace.enableCodeSearch": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.workspace.enableCodeSearch%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.workspace.enableEmbeddingsSearch": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.workspace.enableEmbeddingsSearch%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.workspace.preferredEmbeddingsModel": { + "type": "string", + "default": "", + "markdownDescription": "%github.copilot.config.workspace.preferredEmbeddingsModel%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.workspace.prototypeAdoCodeSearchEndpointOverride": { + "type": "string", + "default": "", + "markdownDescription": "%github.copilot.config.workspace.prototypeAdoCodeSearchEndpointOverride%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.feedback.onChange": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.feedback.onChange%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.review.intent": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.review.intent%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.notebook.summaryExperimentEnabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.notebook.summaryExperimentEnabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.notebook.variableFilteringEnabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.notebook.variableFilteringEnabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.notebook.alternativeFormat": { + "type": "string", + "default": "xml", + "enum": ["xml", "markdown"], + "markdownDescription": "%github.copilot.config.notebook.alternativeFormat%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.notebook.alternativeNESFormat.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.notebook.alternativeNESFormat.enabled%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.debugTerminalCommandPatterns": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "markdownDescription": "%github.copilot.config.debugTerminalCommandPatterns%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.editSourceTracking.showDecorations": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.editSourceTracking.showDecorations%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.editSourceTracking.showStatusBar": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.editSourceTracking.showStatusBar%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.localWorkspaceRecording.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.localWorkspaceRecording.enabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.editRecording.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.editRecording.enabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.temporalContext.maxAge": { + "type": "number", + "default": 100, + "markdownDescription": "%github.copilot.config.temporalContext.maxAge%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.temporalContext.preferSameLang": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.temporalContext.preferSameLang%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.codesearch.agent.enabled": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.codesearch.agent.enabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.agent.temperature": { + "type": ["number", "null"], + "markdownDescription": "%github.copilot.config.agent.temperature%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.instantApply.shortContextModelName": { + "type": "string", + "default": "gpt-4o-instant-apply-full-ft-v66-short", + "markdownDescription": "%github.copilot.config.instantApply.shortContextModelName%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.instantApply.shortContextLimit": { + "type": "number", + "default": 8000, + "markdownDescription": "%github.copilot.config.instantApply.shortContextLimit%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.enableUserPreferences": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.enableUserPreferences%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.summarizeAgentConversationHistoryThreshold": { + "type": ["number", "null"], + "markdownDescription": "%github.copilot.config.summarizeAgentConversationHistoryThreshold%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.agentHistorySummarizationMode": { + "type": ["string", "null"], + "markdownDescription": "%github.copilot.config.agentHistorySummarizationMode%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.agentHistorySummarizationWithPromptCache": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.agentHistorySummarizationWithPromptCache%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.agentHistorySummarizationForceGpt41": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.agentHistorySummarizationForceGpt41%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.useResponsesApiTruncation": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.useResponsesApiTruncation%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.enableReadFileV2": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.enableReadFileV2%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.enableAskAgent": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.enableAskAgent%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.omitBaseAgentInstructions": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.omitBaseAgentInstructions%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.promptFileContextProvider.enabled": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.promptFileContextProvider.enabled%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.tools.defaultToolsGrouped": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.tools.defaultToolsGrouped%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.virtualTools.embeddingRanking": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.virtualTools.embeddingRanking%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.multiReplaceStringGrok.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.multiReplaceStringGrok.enabled%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.claudeCode.enabled": { + "type": ["boolean", "string"], + "default": false, + "markdownDescription": "%github.copilot.config.claudeCode.enabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.claudeCode.debug": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.claudeCode.debug%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.copilotCLI.enabled": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.copilotCLI.enabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.copilotCodingAgent.enabled": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.copilotCodingAgent.enabled%", + "tags": [ + "advanced" + ] + }, + "github.copilot.chat.gpt5AlternativePatch": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.gpt5AlternativePatch%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.inlineEdits.triggerOnEditorChangeAfterSeconds": { + "type": ["number", "null"], + "markdownDescription": "%github.copilot.config.inlineEdits.triggerOnEditorChangeAfterSeconds%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.inlineEdits.nextCursorPrediction.displayLine": { + "type": "boolean", + "default": true, + "markdownDescription": "%github.copilot.config.inlineEdits.nextCursorPrediction.displayLine%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens": { + "type": "number", + "default": 2000, + "markdownDescription": "%github.copilot.config.inlineEdits.nextCursorPrediction.currentFileMaxTokens%", + "tags": [ + "advanced", + "experimental" + ] + } + } } ], "submenus": [ diff --git a/package.nls.json b/package.nls.json index deba2eecd3..d51815ae03 100644 --- a/package.nls.json +++ b/package.nls.json @@ -348,6 +348,52 @@ "github.copilot.config.anthropic.webSearchTool.enabled": "Enable Anthropic's native web search tool for BYOK Claude models. When enabled, allows Claude to search the web for current information. \n\n**Note**: This is an experimental feature only available for BYOK Anthropic Claude models.", "github.copilot.config.completionsFetcher": "Sets the fetcher used for the inline completions.", "github.copilot.config.nesFetcher": "Sets the fetcher used for the next edit suggestions.", + "github.copilot.config.debug.overrideChatEngine": "Override the chat model. This allows you to test with different models.\n\n**Note**: This is an advanced debugging setting and should not be used while self-hosting as it may lead to a different experience compared to end-users.", + "github.copilot.config.projectLabels.expanded": "Use the expanded format for project labels in prompts.", + "github.copilot.config.projectLabels.chat": "Add project labels in chat requests.", + "github.copilot.config.projectLabels.inline": "Add project labels in inline edit requests.", + "github.copilot.config.workspace.maxLocalIndexSize": "Maximum size of the local workspace index.", + "github.copilot.config.workspace.enableFullWorkspace": "Enable full workspace context analysis.", + "github.copilot.config.workspace.enableCodeSearch": "Enable code search in workspace context.", + "github.copilot.config.workspace.enableEmbeddingsSearch": "Enable embeddings-based search in workspace context.", + "github.copilot.config.workspace.preferredEmbeddingsModel": "Preferred embeddings model for semantic search.", + "github.copilot.config.workspace.prototypeAdoCodeSearchEndpointOverride": "Override endpoint for Azure DevOps code search prototype.", + "github.copilot.config.feedback.onChange": "Enable feedback collection on configuration changes.", + "github.copilot.config.review.intent": "Enable intent detection for code review.", + "github.copilot.config.notebook.summaryExperimentEnabled": "Enable the notebook summary experiment.", + "github.copilot.config.notebook.variableFilteringEnabled": "Enable filtering variables by cell document symbols.", + "github.copilot.config.notebook.alternativeFormat": "Alternative document format for notebooks.", + "github.copilot.config.notebook.alternativeNESFormat.enabled": "Enable alternative format for Next Edit Suggestions in notebooks.", + "github.copilot.config.editSourceTracking.showDecorations": "Show decorations for edit source tracking.", + "github.copilot.config.editSourceTracking.showStatusBar": "Show status bar item for edit source tracking.", + "github.copilot.config.localWorkspaceRecording.enabled": "Enable local workspace recording for analysis.", + "github.copilot.config.editRecording.enabled": "Enable edit recording for analysis.", + "github.copilot.config.temporalContext.maxAge": "Maximum age (in editor changes) for temporal context.", + "github.copilot.config.temporalContext.preferSameLang": "Prefer same language files in temporal context.", + "github.copilot.config.codesearch.agent.enabled": "Enable code search capabilities in agent mode.", + "github.copilot.config.agent.temperature": "Temperature setting for agent mode requests.", + "github.copilot.config.instantApply.shortContextModelName": "Model name for short context instant apply.", + "github.copilot.config.instantApply.shortContextLimit": "Token limit for short context instant apply.", + "github.copilot.config.summarizeAgentConversationHistoryThreshold": "Threshold for summarizing agent conversation history.", + "github.copilot.config.agentHistorySummarizationMode": "Mode for agent history summarization.", + "github.copilot.config.agentHistorySummarizationWithPromptCache": "Use prompt caching for agent history summarization.", + "github.copilot.config.agentHistorySummarizationForceGpt41": "Force GPT-4.1 for agent history summarization.", + "github.copilot.config.useResponsesApiTruncation": "Use Responses API for truncation.", + "github.copilot.config.enableReadFileV2": "Enable version 2 of the read file tool.", + "github.copilot.config.enableAskAgent": "Enable the Ask agent for answering questions.", + "github.copilot.config.omitBaseAgentInstructions": "Omit base agent instructions from prompts.", + "github.copilot.config.promptFileContextProvider.enabled": "Enable prompt file context provider.", + "github.copilot.config.tools.defaultToolsGrouped": "Group default tools in prompts.", + "github.copilot.config.virtualTools.embeddingRanking": "Use embedding-based ranking for virtual tools.", + "github.copilot.config.multiReplaceStringGrok.enabled": "Enable multi-replace string with Grok.", + "github.copilot.config.claudeCode.enabled": "Enable Claude Code agent.", + "github.copilot.config.claudeCode.debug": "Enable debug mode for Claude Code agent.", + "github.copilot.config.copilotCLI.enabled": "Enable Copilot CLI integration.", + "github.copilot.config.copilotCodingAgent.enabled": "Enable Copilot Coding Agent (cloud).", + "github.copilot.config.gpt5AlternativePatch": "Enable GPT-5 alternative patch format.", + "github.copilot.config.inlineEdits.triggerOnEditorChangeAfterSeconds": "Trigger inline edits after editor has been idle for this many seconds.", + "github.copilot.config.inlineEdits.nextCursorPrediction.displayLine": "Display predicted cursor line for next edit suggestions.", + "github.copilot.config.inlineEdits.nextCursorPrediction.currentFileMaxTokens": "Maximum tokens for current file in next cursor prediction.", "github.copilot.command.refreshAgentSessions": "Refresh Agent Sessions", "github.copilot.command.deleteAgentSession": "Delete Agent Session", "github.copilot.command.cli.sessions.resumeInTerminal": "Resume Agent Session in Terminal", diff --git a/src/extension/configuration/vscode-node/configurationMigration.ts b/src/extension/configuration/vscode-node/configurationMigration.ts index 936e34657d..c68978cb56 100644 --- a/src/extension/configuration/vscode-node/configurationMigration.ts +++ b/src/extension/configuration/vscode-node/configurationMigration.ts @@ -10,7 +10,7 @@ import { ConfigurationTarget, Uri, window, workspace, WorkspaceFolder } from 'vscode'; -import { Emitter } from '../../../util/vs/base/common/event'; +import { ConfigurationKeyValuePairs, ConfigurationMigration, ConfigurationMigrationRegistry, ConfigurationValue } from '../../../platform/configuration/common/configurationService'; import { DisposableStore, IDisposable } from '../../../util/vs/base/common/lifecycle'; import { localize } from '../../../util/vs/nls'; import { IExtensionContribution } from '../../common/contributions'; @@ -35,28 +35,6 @@ export const Extensions = { ConfigurationMigration: 'base.contributions.configuration.migration' }; -export type ConfigurationValue = { value: any | undefined /* Remove */ }; -export type ConfigurationKeyValuePairs = [string, ConfigurationValue][]; -export type ConfigurationMigrationFn = (value: any) => ConfigurationValue | ConfigurationKeyValuePairs | Promise; -export type ConfigurationMigration = { key: string; migrateFn: ConfigurationMigrationFn }; - -export interface IConfigurationMigrationRegistry { - registerConfigurationMigrations(configurationMigrations: ConfigurationMigration[]): void; -} - -class ConfigurationMigrationRegistryImpl implements IConfigurationMigrationRegistry { - readonly migrations: ConfigurationMigration[] = []; - - private readonly _onDidRegisterConfigurationMigrations = new Emitter(); - readonly onDidRegisterConfigurationMigration = this._onDidRegisterConfigurationMigrations.event; - - registerConfigurationMigrations(configurationMigrations: ConfigurationMigration[]): void { - this.migrations.push(...configurationMigrations); - } -} - -export const ConfigurationMigrationRegistry = new ConfigurationMigrationRegistryImpl(); - export class ConfigurationMigrationContribution implements IExtensionContribution { private readonly _disposables = new DisposableStore(); diff --git a/src/platform/configuration/common/configurationService.ts b/src/platform/configuration/common/configurationService.ts index 99b8281da7..7d0d8905ee 100644 --- a/src/platform/configuration/common/configurationService.ts +++ b/src/platform/configuration/common/configurationService.ts @@ -492,6 +492,30 @@ class ConfigRegistry { export const globalConfigRegistry = new ConfigRegistry(); +// Configuration Migration Types and Registry +export type ConfigurationValue = { value: any | undefined /* Remove */ }; +export type ConfigurationKeyValuePairs = [string, ConfigurationValue][]; +export type ConfigurationMigrationFn = (value: any) => ConfigurationValue | ConfigurationKeyValuePairs | Promise; +export type ConfigurationMigration = { key: string; migrateFn: ConfigurationMigrationFn }; + +export interface IConfigurationMigrationRegistry { + registerConfigurationMigrations(configurationMigrations: ConfigurationMigration[]): void; +} + +class ConfigurationMigrationRegistryImpl implements IConfigurationMigrationRegistry { + readonly migrations: ConfigurationMigration[] = []; + + private readonly _onDidRegisterConfigurationMigrations = new Emitter(); + readonly onDidRegisterConfigurationMigration = this._onDidRegisterConfigurationMigrations.event; + + registerConfigurationMigrations(configurationMigrations: ConfigurationMigration[]): void { + this.migrations.push(...configurationMigrations); + this._onDidRegisterConfigurationMigrations.fire(configurationMigrations); + } +} + +export const ConfigurationMigrationRegistry = new ConfigurationMigrationRegistryImpl(); + function defineValidatedSetting(key: string, validator: IValidator, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions): Config { const value: Config = { ...toBaseConfig(key, defaultValue, options), configType: ConfigType.Simple, validator }; globalConfigRegistry.registerConfig(value); @@ -504,6 +528,20 @@ function defineSetting(key: string, defaultValue: T | DefaultValueWithTeamVal return value; } +function defineAndMigrateSetting(oldKey: string, newKey: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions): Config { + const value = defineSetting(newKey, defaultValue, options); + ConfigurationMigrationRegistry.registerConfigurationMigrations([{ + key: `${CopilotConfigPrefix}.${oldKey}`, + migrateFn: async (migrationValue: any) => { + return [ + [`${CopilotConfigPrefix}.${newKey}`, { value: migrationValue }], + [`${CopilotConfigPrefix}.${oldKey}`, { value: undefined }] + ]; + } + }]); + return value; +} + /** * Will define a setting which will be backed by an experiment. The experiment variable will be: * ``` @@ -523,6 +561,20 @@ export function defineExpSetting(key: strin return value; } +export function defineAndMigrateExpSetting(oldKey: string, newKey: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions, expOptions?: { experimentName?: string }): ExperimentBasedConfig { + const value = defineExpSetting(newKey, defaultValue, options, expOptions); + ConfigurationMigrationRegistry.registerConfigurationMigrations([{ + key: `${CopilotConfigPrefix}.${oldKey}`, + migrateFn: async (migrationValue: any) => { + return [ + [`${CopilotConfigPrefix}.${newKey}`, { value: migrationValue }], + [`${CopilotConfigPrefix}.${oldKey}`, { value: undefined }] + ]; + } + }]); + return value; +} + // Max CAPI tool count limit export const HARD_TOOL_LIMIT = 128; @@ -604,7 +656,7 @@ export namespace ConfigKey { * Note: this should not be used while self-hosting because it might lead to * a fundamental different experience compared to our end-users. */ - export const DebugOverrideChatEngine = defineSetting('chat.advanced.debug.overrideChatEngine', undefined, INTERNAL); + export const DebugOverrideChatEngine = defineAndMigrateSetting('chat.advanced.debug.overrideChatEngine', 'chat.debug.overrideChatEngine', undefined); /** Allows forcing a particular context window size. * This setting doesn't validate values so large windows may not be supported by the model. * Note: this should not be used while self-hosting because it might lead to @@ -622,26 +674,26 @@ export namespace ConfigKey { export const GitHistoryRelatedFilesUsingEmbeddings = defineSetting('chat.advanced.suggestRelatedFilesFromGitHistory.useEmbeddings', false); /** Uses new expanded project labels */ - export const ProjectLabelsExpanded = defineExpSetting('chat.advanced.projectLabels.expanded', false, INTERNAL); + export const ProjectLabelsExpanded = defineAndMigrateExpSetting('chat.advanced.projectLabels.expanded', 'chat.projectLabels.expanded', false); /** Add project labels in default agent */ - export const ProjectLabelsChat = defineExpSetting('chat.advanced.projectLabels.chat', false, INTERNAL); + export const ProjectLabelsChat = defineAndMigrateExpSetting('chat.advanced.projectLabels.chat', 'chat.projectLabels.chat', false); /** Add project labels in default agent */ - export const ProjectLabelsInline = defineExpSetting('chat.advanced.projectLabels.inline', false, INTERNAL); - export const WorkspaceMaxLocalIndexSize = defineExpSetting('chat.advanced.workspace.maxLocalIndexSize', 100_000, INTERNAL); - export const WorkspaceEnableFullWorkspace = defineExpSetting('chat.advanced.workspace.enableFullWorkspace', true, INTERNAL); - export const WorkspaceEnableCodeSearch = defineExpSetting('chat.advanced.workspace.enableCodeSearch', true, INTERNAL); - export const WorkspaceEnableEmbeddingsSearch = defineExpSetting('chat.advanced.workspace.enableEmbeddingsSearch', true, INTERNAL); - export const WorkspacePreferredEmbeddingsModel = defineExpSetting('chat.advanced.workspace.preferredEmbeddingsModel', '', INTERNAL); - export const WorkspacePrototypeAdoCodeSearchEndpointOverride = defineSetting('chat.advanced.workspace.prototypeAdoCodeSearchEndpointOverride', '', INTERNAL); - export const FeedbackOnChange = defineSetting('chat.advanced.feedback.onChange', false, INTERNAL); - export const ReviewIntent = defineSetting('chat.advanced.review.intent', false, INTERNAL); + export const ProjectLabelsInline = defineAndMigrateExpSetting('chat.advanced.projectLabels.inline', 'chat.projectLabels.inline', false); + export const WorkspaceMaxLocalIndexSize = defineAndMigrateExpSetting('chat.advanced.workspace.maxLocalIndexSize', 'chat.workspace.maxLocalIndexSize', 100_000); + export const WorkspaceEnableFullWorkspace = defineAndMigrateExpSetting('chat.advanced.workspace.enableFullWorkspace', 'chat.workspace.enableFullWorkspace', true); + export const WorkspaceEnableCodeSearch = defineAndMigrateExpSetting('chat.advanced.workspace.enableCodeSearch', 'chat.workspace.enableCodeSearch', true); + export const WorkspaceEnableEmbeddingsSearch = defineAndMigrateExpSetting('chat.advanced.workspace.enableEmbeddingsSearch', 'chat.workspace.enableEmbeddingsSearch', true); + export const WorkspacePreferredEmbeddingsModel = defineAndMigrateExpSetting('chat.advanced.workspace.preferredEmbeddingsModel', 'chat.workspace.preferredEmbeddingsModel', ''); + export const WorkspacePrototypeAdoCodeSearchEndpointOverride = defineAndMigrateSetting('chat.advanced.workspace.prototypeAdoCodeSearchEndpointOverride', 'chat.workspace.prototypeAdoCodeSearchEndpointOverride', ''); + export const FeedbackOnChange = defineAndMigrateSetting('chat.advanced.feedback.onChange', 'chat.feedback.onChange', false); + export const ReviewIntent = defineAndMigrateSetting('chat.advanced.review.intent', 'chat.review.intent', false); /** Enable the new notebook priorities experiment */ - export const NotebookSummaryExperimentEnabled = defineSetting('chat.advanced.notebook.summaryExperimentEnabled', false, INTERNAL); + export const NotebookSummaryExperimentEnabled = defineAndMigrateSetting('chat.advanced.notebook.summaryExperimentEnabled', 'chat.notebook.summaryExperimentEnabled', false); /** Enable filtering variables by cell document symbols */ - export const NotebookVariableFilteringEnabled = defineSetting('chat.advanced.notebook.variableFilteringEnabled', false, INTERNAL); - export const NotebookAlternativeDocumentFormat = defineExpSetting('chat.advanced.notebook.alternativeFormat', AlternativeNotebookFormat.xml, INTERNAL); - export const UseAlternativeNESNotebookFormat = defineExpSetting('chat.advanced.notebook.alternativeNESFormat.enabled', false, INTERNAL); - export const TerminalToDebuggerPatterns = defineSetting('chat.advanced.debugTerminalCommandPatterns', [], INTERNAL); + export const NotebookVariableFilteringEnabled = defineAndMigrateSetting('chat.advanced.notebook.variableFilteringEnabled', 'chat.notebook.variableFilteringEnabled', false); + export const NotebookAlternativeDocumentFormat = defineAndMigrateExpSetting('chat.advanced.notebook.alternativeFormat', 'chat.notebook.alternativeFormat', AlternativeNotebookFormat.xml); + export const UseAlternativeNESNotebookFormat = defineAndMigrateExpSetting('chat.advanced.notebook.alternativeNESFormat.enabled', 'chat.notebook.alternativeNESFormat.enabled', false); + export const TerminalToDebuggerPatterns = defineAndMigrateSetting('chat.advanced.debugTerminalCommandPatterns', 'chat.debugTerminalCommandPatterns', []); export const InlineEditsIgnoreCompletionsDisablement = defineValidatedSetting('chat.advanced.inlineEdits.ignoreCompletionsDisablement', vBoolean(), false, INTERNAL_RESTRICTED); export const InlineEditsAsyncCompletions = defineExpSetting('chat.advanced.inlineEdits.asyncCompletions', true, INTERNAL_RESTRICTED); export const InlineEditsDebounceUseCoreRequestTime = defineExpSetting('chat.advanced.inlineEdits.debounceUseCoreRequestTime', false, INTERNAL_RESTRICTED); @@ -662,9 +714,9 @@ export namespace ConfigKey { export const InlineEditsHideInternalInterface = defineValidatedSetting('chat.advanced.inlineEdits.hideInternalInterface', vBoolean(), false, INTERNAL_RESTRICTED); export const InlineEditsLogCancelledRequests = defineValidatedSetting('chat.advanced.inlineEdits.logCancelledRequests', vBoolean(), false, INTERNAL_RESTRICTED); export const InlineEditsUnification = defineExpSetting('chat.advanced.inlineEdits.unification', false, INTERNAL_RESTRICTED); - export const InlineEditsTriggerOnEditorChangeAfterSeconds = defineExpSetting('chat.advanced.inlineEdits.triggerOnEditorChangeAfterSeconds', { defaultValue: undefined, teamDefaultValue: 10 }, INTERNAL); - export const InlineEditsNextCursorPredictionDisplayLine = defineExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.displayLine', true, INTERNAL); - export const InlineEditsNextCursorPredictionCurrentFileMaxTokens = defineExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.currentFileMaxTokens', xtabPromptOptions.DEFAULT_OPTIONS.currentFile.maxTokens, INTERNAL); + export const InlineEditsTriggerOnEditorChangeAfterSeconds = defineAndMigrateExpSetting('chat.advanced.inlineEdits.triggerOnEditorChangeAfterSeconds', 'chat.inlineEdits.triggerOnEditorChangeAfterSeconds', { defaultValue: undefined, teamDefaultValue: 10 }); + export const InlineEditsNextCursorPredictionDisplayLine = defineAndMigrateExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.displayLine', 'chat.inlineEdits.nextCursorPrediction.displayLine', true); + export const InlineEditsNextCursorPredictionCurrentFileMaxTokens = defineAndMigrateExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.currentFileMaxTokens', 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens', xtabPromptOptions.DEFAULT_OPTIONS.currentFile.maxTokens); export const InlineEditsNextCursorPredictionEnabled = defineExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.enabled', { defaultValue: undefined, teamDefaultValue: NextCursorLinePrediction.LabelOnlyWithEdit }, INTERNAL_RESTRICTED); export const InlineEditsNextCursorPredictionModelName = defineExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.modelName', { defaultValue: undefined, teamDefaultValue: "xtab-cursor-jump-v2" }, INTERNAL_RESTRICTED); export const InlineEditsNextCursorPredictionUrl = defineValidatedSetting('chat.advanced.inlineEdits.nextCursorPrediction.url', vString(), undefined, INTERNAL_RESTRICTED); @@ -708,39 +760,39 @@ export namespace ConfigKey { export const InlineEditsXtabOnlyMergeConflictLines = defineExpSetting('chat.advanced.inlineEdits.xtabProvider.onlyMergeConflictLines', false, INTERNAL_RESTRICTED); export const InlineEditsUndoInsertionFiltering = defineExpSetting<'v1' | 'v2' | undefined>('chat.advanced.inlineEdits.undoInsertionFiltering', 'v1', INTERNAL_RESTRICTED); export const InlineEditsDiagnosticsExplorationEnabled = defineSetting('chat.advanced.inlineEdits.inlineEditsDiagnosticsExplorationEnabled', false, INTERNAL_RESTRICTED); - export const EditSourceTrackingShowDecorations = defineSetting('chat.advanced.editSourceTracking.showDecorations', false, INTERNAL); - export const EditSourceTrackingShowStatusBar = defineSetting('chat.advanced.editSourceTracking.showStatusBar', false, INTERNAL); - export const WorkspaceRecordingEnabled = defineSetting('chat.advanced.localWorkspaceRecording.enabled', false, INTERNAL); - export const EditRecordingEnabled = defineSetting('chat.advanced.editRecording.enabled', false, INTERNAL); + export const EditSourceTrackingShowDecorations = defineAndMigrateSetting('chat.advanced.editSourceTracking.showDecorations', 'chat.editSourceTracking.showDecorations', false); + export const EditSourceTrackingShowStatusBar = defineAndMigrateSetting('chat.advanced.editSourceTracking.showStatusBar', 'chat.editSourceTracking.showStatusBar', false); + export const WorkspaceRecordingEnabled = defineAndMigrateSetting('chat.advanced.localWorkspaceRecording.enabled', 'chat.localWorkspaceRecording.enabled', false); + export const EditRecordingEnabled = defineAndMigrateSetting('chat.advanced.editRecording.enabled', 'chat.editRecording.enabled', false); export const InternalWelcomeHintEnabled = defineSetting('chat.advanced.welcomePageHint.enabled', { defaultValue: false, internalDefaultValue: true, teamDefaultValue: true }, INTERNAL_RESTRICTED); /** Configure temporal context max age */ - export const TemporalContextMaxAge = defineExpSetting('chat.advanced.temporalContext.maxAge', 100, INTERNAL); - export const TemporalContextPreferSameLang = defineExpSetting('chat.advanced.temporalContext.preferSameLang', false, INTERNAL); - export const CodeSearchAgentEnabled = defineSetting('chat.advanced.codesearch.agent.enabled', true, INTERNAL); - export const AgentTemperature = defineSetting('chat.advanced.agent.temperature', undefined, INTERNAL); + export const TemporalContextMaxAge = defineAndMigrateExpSetting('chat.advanced.temporalContext.maxAge', 'chat.temporalContext.maxAge', 100); + export const TemporalContextPreferSameLang = defineAndMigrateExpSetting('chat.advanced.temporalContext.preferSameLang', 'chat.temporalContext.preferSameLang', false); + export const CodeSearchAgentEnabled = defineAndMigrateSetting('chat.advanced.codesearch.agent.enabled', 'chat.codesearch.agent.enabled', true); + export const AgentTemperature = defineAndMigrateSetting('chat.advanced.agent.temperature', 'chat.agent.temperature', undefined); export const InlineChatUseCodeMapper = defineSetting('chat.advanced.inlineChat.useCodeMapper', false, INTERNAL_RESTRICTED); export const InstantApplyModelName = defineExpSetting('chat.advanced.instantApply.modelName', 'gpt-4o-instant-apply-full-ft-v66', INTERNAL_RESTRICTED); - export const InstantApplyShortModelName = defineExpSetting('chat.advanced.instantApply.shortContextModelName', CHAT_MODEL.SHORT_INSTANT_APPLY, INTERNAL); - export const InstantApplyShortContextLimit = defineExpSetting('chat.advanced.instantApply.shortContextLimit', 8000, INTERNAL); + export const InstantApplyShortModelName = defineAndMigrateExpSetting('chat.advanced.instantApply.shortContextModelName', 'chat.instantApply.shortContextModelName', CHAT_MODEL.SHORT_INSTANT_APPLY); + export const InstantApplyShortContextLimit = defineAndMigrateExpSetting('chat.advanced.instantApply.shortContextLimit', 'chat.instantApply.shortContextLimit', 8000); - export const EnableUserPreferences = defineSetting('chat.advanced.enableUserPreferences', false, INTERNAL); + export const EnableUserPreferences = defineAndMigrateSetting('chat.advanced.enableUserPreferences', 'chat.enableUserPreferences', false); - export const SummarizeAgentConversationHistoryThreshold = defineSetting('chat.advanced.summarizeAgentConversationHistoryThreshold', undefined, INTERNAL); - export const AgentHistorySummarizationMode = defineSetting('chat.advanced.agentHistorySummarizationMode', undefined, INTERNAL); - export const AgentHistorySummarizationWithPromptCache = defineExpSetting('chat.advanced.agentHistorySummarizationWithPromptCache', false, INTERNAL); - export const AgentHistorySummarizationForceGpt41 = defineExpSetting('chat.advanced.agentHistorySummarizationForceGpt41', false, INTERNAL); + export const SummarizeAgentConversationHistoryThreshold = defineAndMigrateSetting('chat.advanced.summarizeAgentConversationHistoryThreshold', 'chat.summarizeAgentConversationHistoryThreshold', undefined); + export const AgentHistorySummarizationMode = defineAndMigrateSetting('chat.advanced.agentHistorySummarizationMode', 'chat.agentHistorySummarizationMode', undefined); + export const AgentHistorySummarizationWithPromptCache = defineAndMigrateExpSetting('chat.advanced.agentHistorySummarizationWithPromptCache', 'chat.agentHistorySummarizationWithPromptCache', false); + export const AgentHistorySummarizationForceGpt41 = defineAndMigrateExpSetting('chat.advanced.agentHistorySummarizationForceGpt41', 'chat.agentHistorySummarizationForceGpt41', false); export const UseResponsesApiTruncation = defineSetting('chat.advanced.useResponsesApiTruncation', false); export const EnableReadFileV2 = defineExpSetting('chat.advanced.enableReadFileV2', isPreRelease); export const AskAgent = defineExpSetting('chat.advanced.enableAskAgent', { defaultValue: false, teamDefaultValue: true, internalDefaultValue: true }); export const VerifyTextDocumentChanges = defineExpSetting('chat.advanced.inlineEdits.verifyTextDocumentChanges', false, INTERNAL_RESTRICTED); - export const OmitBaseAgentInstructions = defineSetting('chat.advanced.omitBaseAgentInstructions', false, INTERNAL); + export const OmitBaseAgentInstructions = defineAndMigrateSetting('chat.advanced.omitBaseAgentInstructions', 'chat.omitBaseAgentInstructions', false); export const PromptFileContext = defineExpSetting('chat.advanced.promptFileContextProvider.enabled', true); - export const DefaultToolsGrouped = defineExpSetting('chat.advanced.tools.defaultToolsGrouped', false, INTERNAL); - export const VirtualToolEmbeddingRanking = defineExpSetting('chat.advanced.virtualTools.embeddingRanking', false, INTERNAL); - export const MultiReplaceStringGrok = defineExpSetting('chat.advanced.multiReplaceStringGrok.enabled', false, INTERNAL); + export const DefaultToolsGrouped = defineAndMigrateExpSetting('chat.advanced.tools.defaultToolsGrouped', 'chat.tools.defaultToolsGrouped', false); + export const VirtualToolEmbeddingRanking = defineAndMigrateExpSetting('chat.advanced.virtualTools.embeddingRanking', 'chat.virtualTools.embeddingRanking', false); + export const MultiReplaceStringGrok = defineAndMigrateExpSetting('chat.advanced.multiReplaceStringGrok.enabled', 'chat.multiReplaceStringGrok.enabled', false); export const EnableClaudeCodeAgent = defineSetting('chat.advanced.claudeCode.enabled', false); export const ClaudeCodeDebugEnabled = defineSetting('chat.advanced.claudeCode.debug', false); diff --git a/src/platform/configuration/test/common/configurationService.spec.ts b/src/platform/configuration/test/common/configurationService.spec.ts index a4a986e2a9..d015490b26 100644 --- a/src/platform/configuration/test/common/configurationService.spec.ts +++ b/src/platform/configuration/test/common/configurationService.spec.ts @@ -56,250 +56,219 @@ suite('AbstractConfigurationService', () => { suite('Internal Settings - Validation', () => { test('ProjectLabelsChat is correctly configured', () => { const setting = ConfigKey.Internal.ProjectLabelsChat; - assert.strictEqual(setting.id, 'chat.advanced.projectLabels.chat'); + assert.strictEqual(setting.id, 'chat.projectLabels.chat'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('ProjectLabelsInline is correctly configured', () => { const setting = ConfigKey.Internal.ProjectLabelsInline; - assert.strictEqual(setting.id, 'chat.advanced.projectLabels.inline'); + assert.strictEqual(setting.id, 'chat.projectLabels.inline'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('ProjectLabelsExpanded is correctly configured', () => { const setting = ConfigKey.Internal.ProjectLabelsExpanded; - assert.strictEqual(setting.id, 'chat.advanced.projectLabels.expanded'); + assert.strictEqual(setting.id, 'chat.projectLabels.expanded'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspaceMaxLocalIndexSize is correctly configured', () => { const setting = ConfigKey.Internal.WorkspaceMaxLocalIndexSize; - assert.strictEqual(setting.id, 'chat.advanced.workspace.maxLocalIndexSize'); + assert.strictEqual(setting.id, 'chat.workspace.maxLocalIndexSize'); assert.strictEqual(setting.defaultValue, 100_000); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableFullWorkspace is correctly configured', () => { const setting = ConfigKey.Internal.WorkspaceEnableFullWorkspace; - assert.strictEqual(setting.id, 'chat.advanced.workspace.enableFullWorkspace'); + assert.strictEqual(setting.id, 'chat.workspace.enableFullWorkspace'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableCodeSearch is correctly configured', () => { const setting = ConfigKey.Internal.WorkspaceEnableCodeSearch; - assert.strictEqual(setting.id, 'chat.advanced.workspace.enableCodeSearch'); + assert.strictEqual(setting.id, 'chat.workspace.enableCodeSearch'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableEmbeddingsSearch is correctly configured', () => { const setting = ConfigKey.Internal.WorkspaceEnableEmbeddingsSearch; - assert.strictEqual(setting.id, 'chat.advanced.workspace.enableEmbeddingsSearch'); + assert.strictEqual(setting.id, 'chat.workspace.enableEmbeddingsSearch'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspacePreferredEmbeddingsModel is correctly configured', () => { const setting = ConfigKey.Internal.WorkspacePreferredEmbeddingsModel; - assert.strictEqual(setting.id, 'chat.advanced.workspace.preferredEmbeddingsModel'); + assert.strictEqual(setting.id, 'chat.workspace.preferredEmbeddingsModel'); assert.strictEqual(setting.defaultValue, ''); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspacePrototypeAdoCodeSearchEndpointOverride is correctly configured', () => { const setting = ConfigKey.Internal.WorkspacePrototypeAdoCodeSearchEndpointOverride; - assert.strictEqual(setting.id, 'chat.advanced.workspace.prototypeAdoCodeSearchEndpointOverride'); + assert.strictEqual(setting.id, 'chat.workspace.prototypeAdoCodeSearchEndpointOverride'); assert.strictEqual(setting.defaultValue, ''); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('FeedbackOnChange is correctly configured', () => { const setting = ConfigKey.Internal.FeedbackOnChange; - assert.strictEqual(setting.id, 'chat.advanced.feedback.onChange'); + assert.strictEqual(setting.id, 'chat.feedback.onChange'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('ReviewIntent is correctly configured', () => { const setting = ConfigKey.Internal.ReviewIntent; - assert.strictEqual(setting.id, 'chat.advanced.review.intent'); + assert.strictEqual(setting.id, 'chat.review.intent'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('NotebookSummaryExperimentEnabled is correctly configured', () => { const setting = ConfigKey.Internal.NotebookSummaryExperimentEnabled; - assert.strictEqual(setting.id, 'chat.advanced.notebook.summaryExperimentEnabled'); + assert.strictEqual(setting.id, 'chat.notebook.summaryExperimentEnabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('NotebookVariableFilteringEnabled is correctly configured', () => { const setting = ConfigKey.Internal.NotebookVariableFilteringEnabled; - assert.strictEqual(setting.id, 'chat.advanced.notebook.variableFilteringEnabled'); + assert.strictEqual(setting.id, 'chat.notebook.variableFilteringEnabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('NotebookAlternativeDocumentFormat is correctly configured', () => { const setting = ConfigKey.Internal.NotebookAlternativeDocumentFormat; - assert.strictEqual(setting.id, 'chat.advanced.notebook.alternativeFormat'); + assert.strictEqual(setting.id, 'chat.notebook.alternativeFormat'); assert.strictEqual(setting.defaultValue, AlternativeNotebookFormat.xml); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('UseAlternativeNESNotebookFormat is correctly configured', () => { const setting = ConfigKey.Internal.UseAlternativeNESNotebookFormat; - assert.strictEqual(setting.id, 'chat.advanced.notebook.alternativeNESFormat.enabled'); + assert.strictEqual(setting.id, 'chat.notebook.alternativeNESFormat.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('TerminalToDebuggerPatterns is correctly configured', () => { const setting = ConfigKey.Internal.TerminalToDebuggerPatterns; - assert.strictEqual(setting.id, 'chat.advanced.debugTerminalCommandPatterns'); + assert.strictEqual(setting.id, 'chat.debugTerminalCommandPatterns'); assert.deepStrictEqual(setting.defaultValue, []); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('EditSourceTrackingShowDecorations is correctly configured', () => { const setting = ConfigKey.Internal.EditSourceTrackingShowDecorations; - assert.strictEqual(setting.id, 'chat.advanced.editSourceTracking.showDecorations'); + assert.strictEqual(setting.id, 'chat.editSourceTracking.showDecorations'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('EditSourceTrackingShowStatusBar is correctly configured', () => { const setting = ConfigKey.Internal.EditSourceTrackingShowStatusBar; - assert.strictEqual(setting.id, 'chat.advanced.editSourceTracking.showStatusBar'); + assert.strictEqual(setting.id, 'chat.editSourceTracking.showStatusBar'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('WorkspaceRecordingEnabled is correctly configured', () => { const setting = ConfigKey.Internal.WorkspaceRecordingEnabled; - assert.strictEqual(setting.id, 'chat.advanced.localWorkspaceRecording.enabled'); + assert.strictEqual(setting.id, 'chat.localWorkspaceRecording.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('EditRecordingEnabled is correctly configured', () => { const setting = ConfigKey.Internal.EditRecordingEnabled; - assert.strictEqual(setting.id, 'chat.advanced.editRecording.enabled'); + assert.strictEqual(setting.id, 'chat.editRecording.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('TemporalContextMaxAge is correctly configured', () => { const setting = ConfigKey.Internal.TemporalContextMaxAge; - assert.strictEqual(setting.id, 'chat.advanced.temporalContext.maxAge'); + assert.strictEqual(setting.id, 'chat.temporalContext.maxAge'); assert.strictEqual(setting.defaultValue, 100); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('TemporalContextPreferSameLang is correctly configured', () => { const setting = ConfigKey.Internal.TemporalContextPreferSameLang; - assert.strictEqual(setting.id, 'chat.advanced.temporalContext.preferSameLang'); + assert.strictEqual(setting.id, 'chat.temporalContext.preferSameLang'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('CodeSearchAgentEnabled is correctly configured', () => { const setting = ConfigKey.Internal.CodeSearchAgentEnabled; - assert.strictEqual(setting.id, 'chat.advanced.codesearch.agent.enabled'); + assert.strictEqual(setting.id, 'chat.codesearch.agent.enabled'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('AgentTemperature is correctly configured', () => { const setting = ConfigKey.Internal.AgentTemperature; - assert.strictEqual(setting.id, 'chat.advanced.agent.temperature'); + assert.strictEqual(setting.id, 'chat.agent.temperature'); assert.strictEqual(setting.defaultValue, undefined); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('InstantApplyShortModelName is correctly configured', () => { const setting = ConfigKey.Internal.InstantApplyShortModelName; - assert.strictEqual(setting.id, 'chat.advanced.instantApply.shortContextModelName'); + assert.strictEqual(setting.id, 'chat.instantApply.shortContextModelName'); assert.strictEqual(setting.defaultValue, 'gpt-4o-instant-apply-full-ft-v66-short'); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('InstantApplyShortContextLimit is correctly configured', () => { const setting = ConfigKey.Internal.InstantApplyShortContextLimit; - assert.strictEqual(setting.id, 'chat.advanced.instantApply.shortContextLimit'); + assert.strictEqual(setting.id, 'chat.instantApply.shortContextLimit'); assert.strictEqual(setting.defaultValue, 8000); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('EnableUserPreferences is correctly configured', () => { const setting = ConfigKey.Internal.EnableUserPreferences; - assert.strictEqual(setting.id, 'chat.advanced.enableUserPreferences'); + assert.strictEqual(setting.id, 'chat.enableUserPreferences'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('SummarizeAgentConversationHistoryThreshold is correctly configured', () => { const setting = ConfigKey.Internal.SummarizeAgentConversationHistoryThreshold; - assert.strictEqual(setting.id, 'chat.advanced.summarizeAgentConversationHistoryThreshold'); + assert.strictEqual(setting.id, 'chat.summarizeAgentConversationHistoryThreshold'); assert.strictEqual(setting.defaultValue, undefined); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationMode is correctly configured', () => { const setting = ConfigKey.Internal.AgentHistorySummarizationMode; - assert.strictEqual(setting.id, 'chat.advanced.agentHistorySummarizationMode'); + assert.strictEqual(setting.id, 'chat.agentHistorySummarizationMode'); assert.strictEqual(setting.defaultValue, undefined); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationWithPromptCache is correctly configured', () => { const setting = ConfigKey.Internal.AgentHistorySummarizationWithPromptCache; - assert.strictEqual(setting.id, 'chat.advanced.agentHistorySummarizationWithPromptCache'); + assert.strictEqual(setting.id, 'chat.agentHistorySummarizationWithPromptCache'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationForceGpt41 is correctly configured', () => { const setting = ConfigKey.Internal.AgentHistorySummarizationForceGpt41; - assert.strictEqual(setting.id, 'chat.advanced.agentHistorySummarizationForceGpt41'); + assert.strictEqual(setting.id, 'chat.agentHistorySummarizationForceGpt41'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('UseResponsesApiTruncation is correctly configured', () => { @@ -312,10 +281,9 @@ suite('AbstractConfigurationService', () => { test('OmitBaseAgentInstructions is correctly configured', () => { const setting = ConfigKey.Internal.OmitBaseAgentInstructions; - assert.strictEqual(setting.id, 'chat.advanced.omitBaseAgentInstructions'); + assert.strictEqual(setting.id, 'chat.omitBaseAgentInstructions'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('PromptFileContext is correctly configured', () => { @@ -328,26 +296,23 @@ suite('AbstractConfigurationService', () => { test('DefaultToolsGrouped is correctly configured', () => { const setting = ConfigKey.Internal.DefaultToolsGrouped; - assert.strictEqual(setting.id, 'chat.advanced.tools.defaultToolsGrouped'); + assert.strictEqual(setting.id, 'chat.tools.defaultToolsGrouped'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('VirtualToolEmbeddingRanking is correctly configured', () => { const setting = ConfigKey.Internal.VirtualToolEmbeddingRanking; - assert.strictEqual(setting.id, 'chat.advanced.virtualTools.embeddingRanking'); + assert.strictEqual(setting.id, 'chat.virtualTools.embeddingRanking'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('MultiReplaceStringGrok is correctly configured', () => { const setting = ConfigKey.Internal.MultiReplaceStringGrok; - assert.strictEqual(setting.id, 'chat.advanced.multiReplaceStringGrok.enabled'); + assert.strictEqual(setting.id, 'chat.multiReplaceStringGrok.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('EnableClaudeCodeAgent is correctly configured', () => { @@ -392,28 +357,25 @@ suite('AbstractConfigurationService', () => { test('InlineEditsTriggerOnEditorChangeAfterSeconds is correctly configured', () => { const setting = ConfigKey.Internal.InlineEditsTriggerOnEditorChangeAfterSeconds; - assert.strictEqual(setting.id, 'chat.advanced.inlineEdits.triggerOnEditorChangeAfterSeconds'); + assert.strictEqual(setting.id, 'chat.inlineEdits.triggerOnEditorChangeAfterSeconds'); const defaultValue = setting.defaultValue as DefaultValueWithTeamValue; assert.strictEqual(defaultValue.defaultValue, undefined); assert.strictEqual(defaultValue.teamDefaultValue, 10); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('InlineEditsNextCursorPredictionDisplayLine is correctly configured', () => { const setting = ConfigKey.Internal.InlineEditsNextCursorPredictionDisplayLine; - assert.strictEqual(setting.id, 'chat.advanced.inlineEdits.nextCursorPrediction.displayLine'); + assert.strictEqual(setting.id, 'chat.inlineEdits.nextCursorPrediction.displayLine'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); test('InlineEditsNextCursorPredictionCurrentFileMaxTokens is correctly configured', () => { const setting = ConfigKey.Internal.InlineEditsNextCursorPredictionCurrentFileMaxTokens; - assert.strictEqual(setting.id, 'chat.advanced.inlineEdits.nextCursorPrediction.currentFileMaxTokens'); + assert.strictEqual(setting.id, 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens'); assert.strictEqual(setting.defaultValue, 2000); - assert.strictEqual(setting.isPublic, false); - + assert.strictEqual(setting.isPublic, true); }); }); From af14dedb57fea5919429fa3b30ff238bf7452608 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 11 Nov 2025 16:31:41 +0100 Subject: [PATCH 2/7] support old key while - reading config value - reading experiment - listening to changes --- package.json | 184 ++++++++++------ package.nls.json | 3 + .../agents/claude/node/claudeCodeAgent.ts | 2 +- .../agents/copilotcli/node/mcpHandler.ts | 2 +- .../copilotCLIChatSessionsContribution.ts | 2 +- .../copilotCLITerminalIntegration.ts | 2 +- .../node/resolvers/promptWorkspaceLabels.ts | 2 +- .../vscode-node/feedbackCollection.ts | 2 +- .../inlineEdits/node/nextEditCache.ts | 2 +- .../inlineEdits/node/nextEditProvider.ts | 2 +- .../diagnosticsCompletionProcessor.ts | 2 +- .../vscode-node/inlineCompletionProvider.ts | 2 +- .../vscode-node/inlineEditModel.ts | 4 +- .../vscode-node/inlineEditProviderFeature.ts | 2 +- .../vscode-node/parts/vscodeWorkspace.ts | 2 +- src/extension/intents/node/agentIntent.ts | 10 +- src/extension/intents/node/askAgentIntent.ts | 2 +- src/extension/intents/node/editCodeIntent.ts | 2 +- src/extension/intents/node/editCodeIntent2.ts | 4 +- .../intents/node/notebookEditorIntent.ts | 2 +- .../node/debuggableCommandIdentifier.ts | 2 +- .../node/debuggableCommandIdentifier.spec.ts | 4 +- .../vscode-node/endpointProviderImpl.ts | 2 +- .../vscode-node/promptFileContextService.ts | 2 +- .../prompts/node/agent/agentPrompt.tsx | 2 +- .../node/agent/defaultAgentInstructions.tsx | 4 +- .../agent/summarizedConversationHistory.tsx | 6 +- .../node/agent/test/agentPrompt.spec.tsx | 2 +- .../prompts/node/codeMapper/codeMapper.ts | 2 +- .../node/inline/inlineChatEditCodePrompt.tsx | 2 +- .../inline/inlineChatGenerateCodePrompt.tsx | 2 +- .../inlineChatNotebookGeneratePrompt.tsx | 2 +- .../prompts/node/inline/temporalContext.tsx | 4 +- .../prompts/node/panel/editCodePrompt.tsx | 4 +- .../prompts/node/panel/editCodePrompt2.tsx | 4 +- .../node/panel/notebookInlinePrompt.tsx | 4 +- .../node/panel/panelChatBasePrompt.tsx | 2 +- .../prompts/node/panel/preferences.tsx | 2 +- .../prompts/node/test/temporalContext.spec.ts | 4 +- .../node/gitRelatedFilesProvider.ts | 4 +- .../common/virtualTools/virtualToolGrouper.ts | 2 +- .../vscode-node/workspaceRecorderFeature.ts | 2 +- src/extension/xtab/node/xtabProvider.ts | 2 +- .../common/configurationService.ts | 199 +++++++++--------- .../test/common/configurationService.spec.ts | 88 ++++---- .../vscode/configurationServiceImpl.ts | 48 ++++- .../node/proxyInstantApplyShortEndpoint.ts | 2 +- src/platform/endpoint/node/responsesApi.ts | 2 +- .../multiFileEdit/common/editLogService.ts | 2 +- .../notebook/common/alternativeContent.ts | 2 +- .../notebook/vscode/notebookServiceImpl.ts | 2 +- .../common/adoCodeSearchService.ts | 2 +- .../review/vscode/reviewServiceImpl.ts | 6 +- .../test/node/simulationWorkspaceServices.ts | 6 +- .../common/githubAvailableEmbeddingTypes.ts | 2 +- .../node/codeSearchChunkSearch.ts | 2 +- .../node/embeddingsChunkSearch.ts | 2 +- .../node/fullWorkspaceChunkSearch.ts | 2 +- .../node/workspaceFileIndex.ts | 2 +- 59 files changed, 383 insertions(+), 287 deletions(-) diff --git a/package.json b/package.json index 92e8d18722..96e21159e6 100644 --- a/package.json +++ b/package.json @@ -3340,7 +3340,7 @@ } }, { - "id": "experimental", + "id": "advanced", "properties": { "github.copilot.chat.debug.overrideChatEngine": { "type": [ @@ -3349,7 +3349,8 @@ ], "markdownDescription": "%github.copilot.config.debug.overrideChatEngine%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.projectLabels.expanded": { @@ -3358,7 +3359,8 @@ "markdownDescription": "%github.copilot.config.projectLabels.expanded%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.projectLabels.chat": { @@ -3367,7 +3369,8 @@ "markdownDescription": "%github.copilot.config.projectLabels.chat%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.projectLabels.inline": { @@ -3376,7 +3379,8 @@ "markdownDescription": "%github.copilot.config.projectLabels.inline%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.workspace.maxLocalIndexSize": { @@ -3385,7 +3389,8 @@ "markdownDescription": "%github.copilot.config.workspace.maxLocalIndexSize%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.workspace.enableFullWorkspace": { @@ -3394,7 +3399,8 @@ "markdownDescription": "%github.copilot.config.workspace.enableFullWorkspace%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.workspace.enableCodeSearch": { @@ -3403,7 +3409,8 @@ "markdownDescription": "%github.copilot.config.workspace.enableCodeSearch%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.workspace.enableEmbeddingsSearch": { @@ -3412,7 +3419,8 @@ "markdownDescription": "%github.copilot.config.workspace.enableEmbeddingsSearch%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.workspace.preferredEmbeddingsModel": { @@ -3421,7 +3429,8 @@ "markdownDescription": "%github.copilot.config.workspace.preferredEmbeddingsModel%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.workspace.prototypeAdoCodeSearchEndpointOverride": { @@ -3429,7 +3438,8 @@ "default": "", "markdownDescription": "%github.copilot.config.workspace.prototypeAdoCodeSearchEndpointOverride%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.feedback.onChange": { @@ -3437,7 +3447,8 @@ "default": false, "markdownDescription": "%github.copilot.config.feedback.onChange%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.review.intent": { @@ -3445,7 +3456,8 @@ "default": false, "markdownDescription": "%github.copilot.config.review.intent%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.notebook.summaryExperimentEnabled": { @@ -3453,7 +3465,8 @@ "default": false, "markdownDescription": "%github.copilot.config.notebook.summaryExperimentEnabled%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.notebook.variableFilteringEnabled": { @@ -3461,7 +3474,8 @@ "default": false, "markdownDescription": "%github.copilot.config.notebook.variableFilteringEnabled%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.notebook.alternativeFormat": { @@ -3471,7 +3485,8 @@ "markdownDescription": "%github.copilot.config.notebook.alternativeFormat%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.notebook.alternativeNESFormat.enabled": { @@ -3480,7 +3495,8 @@ "markdownDescription": "%github.copilot.config.notebook.alternativeNESFormat.enabled%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.debugTerminalCommandPatterns": { @@ -3491,7 +3507,8 @@ }, "markdownDescription": "%github.copilot.config.debugTerminalCommandPatterns%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.editSourceTracking.showDecorations": { @@ -3499,7 +3516,8 @@ "default": false, "markdownDescription": "%github.copilot.config.editSourceTracking.showDecorations%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.editSourceTracking.showStatusBar": { @@ -3507,7 +3525,8 @@ "default": false, "markdownDescription": "%github.copilot.config.editSourceTracking.showStatusBar%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.localWorkspaceRecording.enabled": { @@ -3515,7 +3534,8 @@ "default": false, "markdownDescription": "%github.copilot.config.localWorkspaceRecording.enabled%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.editRecording.enabled": { @@ -3523,7 +3543,8 @@ "default": false, "markdownDescription": "%github.copilot.config.editRecording.enabled%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.temporalContext.maxAge": { @@ -3532,7 +3553,8 @@ "markdownDescription": "%github.copilot.config.temporalContext.maxAge%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.temporalContext.preferSameLang": { @@ -3541,7 +3563,8 @@ "markdownDescription": "%github.copilot.config.temporalContext.preferSameLang%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.codesearch.agent.enabled": { @@ -3549,14 +3572,16 @@ "default": true, "markdownDescription": "%github.copilot.config.codesearch.agent.enabled%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.agent.temperature": { "type": ["number", "null"], "markdownDescription": "%github.copilot.config.agent.temperature%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.instantApply.shortContextModelName": { @@ -3565,7 +3590,8 @@ "markdownDescription": "%github.copilot.config.instantApply.shortContextModelName%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.instantApply.shortContextLimit": { @@ -3574,7 +3600,8 @@ "markdownDescription": "%github.copilot.config.instantApply.shortContextLimit%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.enableUserPreferences": { @@ -3582,21 +3609,24 @@ "default": false, "markdownDescription": "%github.copilot.config.enableUserPreferences%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.summarizeAgentConversationHistoryThreshold": { "type": ["number", "null"], "markdownDescription": "%github.copilot.config.summarizeAgentConversationHistoryThreshold%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.agentHistorySummarizationMode": { "type": ["string", "null"], "markdownDescription": "%github.copilot.config.agentHistorySummarizationMode%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.agentHistorySummarizationWithPromptCache": { @@ -3605,7 +3635,8 @@ "markdownDescription": "%github.copilot.config.agentHistorySummarizationWithPromptCache%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.agentHistorySummarizationForceGpt41": { @@ -3614,30 +3645,14 @@ "markdownDescription": "%github.copilot.config.agentHistorySummarizationForceGpt41%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.useResponsesApiTruncation": { "type": "boolean", "default": false, "markdownDescription": "%github.copilot.config.useResponsesApiTruncation%", - "tags": [ - "advanced" - ] - }, - "github.copilot.chat.enableReadFileV2": { - "type": "boolean", - "default": true, - "markdownDescription": "%github.copilot.config.enableReadFileV2%", - "tags": [ - "advanced", - "experimental" - ] - }, - "github.copilot.chat.enableAskAgent": { - "type": "boolean", - "default": false, - "markdownDescription": "%github.copilot.config.enableAskAgent%", "tags": [ "advanced", "experimental" @@ -3648,7 +3663,8 @@ "default": false, "markdownDescription": "%github.copilot.config.omitBaseAgentInstructions%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.promptFileContextProvider.enabled": { @@ -3657,7 +3673,8 @@ "markdownDescription": "%github.copilot.config.promptFileContextProvider.enabled%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.tools.defaultToolsGrouped": { @@ -3666,7 +3683,8 @@ "markdownDescription": "%github.copilot.config.tools.defaultToolsGrouped%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.virtualTools.embeddingRanking": { @@ -3675,7 +3693,8 @@ "markdownDescription": "%github.copilot.config.virtualTools.embeddingRanking%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.multiReplaceStringGrok.enabled": { @@ -3684,7 +3703,8 @@ "markdownDescription": "%github.copilot.config.multiReplaceStringGrok.enabled%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.claudeCode.enabled": { @@ -3692,7 +3712,8 @@ "default": false, "markdownDescription": "%github.copilot.config.claudeCode.enabled%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.claudeCode.debug": { @@ -3700,7 +3721,8 @@ "default": false, "markdownDescription": "%github.copilot.config.claudeCode.debug%", "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.copilotCLI.enabled": { @@ -3708,15 +3730,8 @@ "default": true, "markdownDescription": "%github.copilot.config.copilotCLI.enabled%", "tags": [ - "advanced" - ] - }, - "github.copilot.chat.copilotCodingAgent.enabled": { - "type": "boolean", - "default": true, - "markdownDescription": "%github.copilot.config.copilotCodingAgent.enabled%", - "tags": [ - "advanced" + "advanced", + "experimental" ] }, "github.copilot.chat.gpt5AlternativePatch": { @@ -3725,7 +3740,8 @@ "markdownDescription": "%github.copilot.config.gpt5AlternativePatch%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.inlineEdits.triggerOnEditorChangeAfterSeconds": { @@ -3733,7 +3749,8 @@ "markdownDescription": "%github.copilot.config.inlineEdits.triggerOnEditorChangeAfterSeconds%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.inlineEdits.nextCursorPrediction.displayLine": { @@ -3742,13 +3759,42 @@ "markdownDescription": "%github.copilot.config.inlineEdits.nextCursorPrediction.displayLine%", "tags": [ "advanced", - "experimental" + "experimental", + "onExp" ] }, "github.copilot.chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens": { "type": "number", "default": 2000, "markdownDescription": "%github.copilot.config.inlineEdits.nextCursorPrediction.currentFileMaxTokens%", + "tags": [ + "advanced", + "experimental", + "onExp" + ] + }, + "github.copilot.chat.suggestRelatedFilesFromGitHistory.useEmbeddings": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.suggestRelatedFilesFromGitHistory.useEmbeddings%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.cli.isolation.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.cli.isolation.enabled%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.cli.mcp.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.cli.mcp.enabled%", "tags": [ "advanced", "experimental" diff --git a/package.nls.json b/package.nls.json index e88cdb18cf..d7bd34d18a 100644 --- a/package.nls.json +++ b/package.nls.json @@ -160,6 +160,7 @@ "github.copilot.config.debugTerminalCommandPatterns": "A list of commands for which the \"Debug Command\" quick fix action should be shown in the debug terminal.", "github.copilot.config.edits.suggestRelatedFilesFromGitHistory": "Whether to suggest related files from git history for the Copilot Edits working set.", "github.copilot.chat.edits.suggestRelatedFilesForTests": "Whether to suggest source files from test files for the Copilot Edits working set.", + "github.copilot.config.suggestRelatedFilesFromGitHistory.useEmbeddings": "Use embeddings to suggest related files from git history.", "github.copilot.config.codeGeneration.instructions": "A set of instructions that will be added to Copilot requests that generate code.\nInstructions can come from: \n- a file in the workspace: `{ \"file\": \"fileName\" }`\n- text in natural language: `{ \"text\": \"Use underscore for field names.\" }`\n\nNote: Keep your instructions short and precise. Poor instructions can degrade Copilot's quality and performance.", "github.copilot.config.codeGeneration.instructions.deprecated": "Use instructions files instead. See https://aka.ms/vscode-ghcp-custom-instructions for more information.", "github.copilot.config.codeGeneration.useInstructionFiles": "Controls whether code instructions from `.github/copilot-instructions.md` are added to Copilot requests.\n\nNote: Keep your instructions short and precise. Poor instructions can degrade Copilot's quality and performance. [Learn more](https://aka.ms/github-copilot-custom-instructions) about customizing Copilot.", @@ -404,6 +405,8 @@ "github.copilot.config.claudeCode.enabled": "Enable Claude Code agent.", "github.copilot.config.claudeCode.debug": "Enable debug mode for Claude Code agent.", "github.copilot.config.copilotCLI.enabled": "Enable Copilot CLI integration.", + "github.copilot.config.cli.isolation.enabled": "Enable CLI isolation for agent sessions.", + "github.copilot.config.cli.mcp.enabled": "Enable Model Context Protocol (MCP) server for CLI.", "github.copilot.config.copilotCodingAgent.enabled": "Enable Copilot Coding Agent (cloud).", "github.copilot.config.gpt5AlternativePatch": "Enable GPT-5 alternative patch format.", "github.copilot.config.inlineEdits.triggerOnEditorChangeAfterSeconds": "Trigger inline edits after editor has been idle for this many seconds.", diff --git a/src/extension/agents/claude/node/claudeCodeAgent.ts b/src/extension/agents/claude/node/claudeCodeAgent.ts index 0521c23589..6e3da60faf 100644 --- a/src/extension/agents/claude/node/claudeCodeAgent.ts +++ b/src/extension/agents/claude/node/claudeCodeAgent.ts @@ -238,7 +238,7 @@ export class ClaudeCodeSession extends Disposable { private async _startSession(token: vscode.CancellationToken): Promise { // Build options for the Claude Code SDK // process.env.DEBUG = '1'; // debug messages from sdk.mjs - const isDebugEnabled = this.configService.getConfig(ConfigKey.Internal.ClaudeCodeDebugEnabled); + const isDebugEnabled = this.configService.getConfig(ConfigKey.AdvancedExperimental.ClaudeCodeDebugEnabled); this.logService.trace(`appRoot: ${this.envService.appRoot}`); const pathSep = isWindows ? ';' : ':'; const options: Options = { diff --git a/src/extension/agents/copilotcli/node/mcpHandler.ts b/src/extension/agents/copilotcli/node/mcpHandler.ts index ace93f68d5..c28291908a 100644 --- a/src/extension/agents/copilotcli/node/mcpHandler.ts +++ b/src/extension/agents/copilotcli/node/mcpHandler.ts @@ -89,7 +89,7 @@ export class CopilotCLIMCPHandler implements ICopilotCLIMCPHandler { ) { } public async loadMcpConfig(workingDirectory: string | undefined): Promise | undefined> { - if (!this.configurationService.getConfig(ConfigKey.Internal.CLIMCPServerEnabled)) { + if (!this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CLIMCPServerEnabled)) { return undefined; } diff --git a/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts b/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts index 432c767588..8b54191c92 100644 --- a/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts +++ b/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts @@ -240,7 +240,7 @@ export class CopilotCLIChatSessionContentProvider implements vscode.ChatSessionC [MODELS_OPTION_ID]: _sessionModel.get(copilotcliSessionId)?.id ?? defaultModel.id, }; - if (!existingSession && this.configurationService.getConfig(ConfigKey.Internal.CLIIsolationEnabled)) { + if (!existingSession && this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CLIIsolationEnabled)) { options[ISOLATION_OPTION_ID] = isolationEnabled ? 'enabled' : 'disabled'; } const history = existingSession?.object?.getChatHistory() || []; diff --git a/src/extension/chatSessions/vscode-node/copilotCLITerminalIntegration.ts b/src/extension/chatSessions/vscode-node/copilotCLITerminalIntegration.ts index d6cba61769..d3b9f22ed9 100644 --- a/src/extension/chatSessions/vscode-node/copilotCLITerminalIntegration.ts +++ b/src/extension/chatSessions/vscode-node/copilotCLITerminalIntegration.ts @@ -59,7 +59,7 @@ export class CopilotCLITerminalIntegration extends Disposable implements ICopilo } private async initialize(): Promise { - const enabled = this.configurationService.getConfig(ConfigKey.Internal.CopilotCLIEnabled); + const enabled = this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CopilotCLIEnabled); if (!enabled) { return; } diff --git a/src/extension/context/node/resolvers/promptWorkspaceLabels.ts b/src/extension/context/node/resolvers/promptWorkspaceLabels.ts index 3f5845f16f..f25da68a09 100644 --- a/src/extension/context/node/resolvers/promptWorkspaceLabels.ts +++ b/src/extension/context/node/resolvers/promptWorkspaceLabels.ts @@ -56,7 +56,7 @@ export class PromptWorkspaceLabels implements IPromptWorkspaceLabels { } public async collectContext(): Promise { - const expandedLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.ProjectLabelsExpanded, this._experimentationService); + const expandedLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsExpanded, this._experimentationService); this.strategy = expandedLabels ? PromptWorkspaceLabelsStrategy.Expanded : PromptWorkspaceLabelsStrategy.Basic; await this.workspaceLabels.collectContext(); diff --git a/src/extension/conversation/vscode-node/feedbackCollection.ts b/src/extension/conversation/vscode-node/feedbackCollection.ts index 32b1f2b3d4..ce8320a6e8 100644 --- a/src/extension/conversation/vscode-node/feedbackCollection.ts +++ b/src/extension/conversation/vscode-node/feedbackCollection.ts @@ -25,7 +25,7 @@ export function startFeedbackCollection(accessor: ServicesAccessor) { const instantiationService = accessor.get(IInstantiationService); const logService = accessor.get(ILogService); const disposables = new DisposableStore(); - const enabled = configurationService.getConfig(ConfigKey.Internal.FeedbackOnChange); + const enabled = configurationService.getConfig(ConfigKey.AdvancedExperimental.FeedbackOnChange); if (!enabled) { return disposables; } diff --git a/src/extension/inlineEdits/node/nextEditCache.ts b/src/extension/inlineEdits/node/nextEditCache.ts index 2e72a04c72..02ed75e8ed 100644 --- a/src/extension/inlineEdits/node/nextEditCache.ts +++ b/src/extension/inlineEdits/node/nextEditCache.ts @@ -67,7 +67,7 @@ export class NextEditCache extends Disposable { } // if editor-change triggering is allowed, // it means an edit in file A can result in a cached edit for file B to be less relevant than with the edits in file A included - if (configService.getExperimentBasedConfig(ConfigKey.Internal.InlineEditsTriggerOnEditorChangeAfterSeconds, expService) !== undefined) { + if (configService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.InlineEditsTriggerOnEditorChangeAfterSeconds, expService) !== undefined) { for (const [k, v] of this._sharedCache.entries()) { if (v.docId !== doc.id) { this._sharedCache.deleteKey(k); diff --git a/src/extension/inlineEdits/node/nextEditProvider.ts b/src/extension/inlineEdits/node/nextEditProvider.ts index 1b86ebcf04..0fe6685964 100644 --- a/src/extension/inlineEdits/node/nextEditProvider.ts +++ b/src/extension/inlineEdits/node/nextEditProvider.ts @@ -323,7 +323,7 @@ export class NextEditProvider extends Disposable implements INextEditProvider { completionItem: T | null; diff --git a/src/extension/inlineEdits/vscode-node/inlineCompletionProvider.ts b/src/extension/inlineEdits/vscode-node/inlineCompletionProvider.ts index cccb76fe4c..43805c0a7c 100644 --- a/src/extension/inlineEdits/vscode-node/inlineCompletionProvider.ts +++ b/src/extension/inlineEdits/vscode-node/inlineCompletionProvider.ts @@ -120,7 +120,7 @@ export class InlineCompletionProviderImpl implements InlineCompletionItemProvide @IWorkspaceService private readonly _workspaceService: IWorkspaceService, ) { this._tracer = createTracer(['NES', 'Provider'], (s) => this._logService.trace(s)); - this._displayNextEditorNES = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.UseAlternativeNESNotebookFormat, this._expService); + this._displayNextEditorNES = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.UseAlternativeNESNotebookFormat, this._expService); } // copied from `vscodeWorkspace.ts` `DocumentFilter#_enabledLanguages` diff --git a/src/extension/inlineEdits/vscode-node/inlineEditModel.ts b/src/extension/inlineEdits/vscode-node/inlineEditModel.ts index 413252d911..1699d93a30 100644 --- a/src/extension/inlineEdits/vscode-node/inlineEditModel.ts +++ b/src/extension/inlineEdits/vscode-node/inlineEditModel.ts @@ -217,7 +217,7 @@ export class InlineEditTriggerer extends Disposable { const selectionLine = range.start.line; - const triggerOnActiveEditorChange = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.InlineEditsTriggerOnEditorChangeAfterSeconds, this._expService); + const triggerOnActiveEditorChange = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.InlineEditsTriggerOnEditorChangeAfterSeconds, this._expService); // If we're in a notebook cell, // Its possible user made changes in one cell and now is moving to another cell // In such cases we should account for the possibility of the user wanting to edit the new cell and trigger suggestions. @@ -264,7 +264,7 @@ export class InlineEditTriggerer extends Disposable { private _maybeTriggerOnDocumentSwitch(e: vscode.TextEditorSelectionChangeEvent, isSameDoc: boolean, parentTracer: ITracer): boolean { const tracer = parentTracer.subNoEntry('editorSwitch'); - const triggerAfterSeconds = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.InlineEditsTriggerOnEditorChangeAfterSeconds, this._expService); + const triggerAfterSeconds = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.InlineEditsTriggerOnEditorChangeAfterSeconds, this._expService); if (triggerAfterSeconds === undefined) { tracer.trace('document switch disabled'); return false; diff --git a/src/extension/inlineEdits/vscode-node/inlineEditProviderFeature.ts b/src/extension/inlineEdits/vscode-node/inlineEditProviderFeature.ts index 1b01f3b5c2..cc16c3d00e 100644 --- a/src/extension/inlineEdits/vscode-node/inlineEditProviderFeature.ts +++ b/src/extension/inlineEdits/vscode-node/inlineEditProviderFeature.ts @@ -87,7 +87,7 @@ export class InlineEditProviderFeature extends Disposable implements IExtensionC const tracer = createTracer(['NES', 'Feature'], (s) => this._logService.trace(s)); const constructorTracer = tracer.sub('constructor'); const hasUpdatedNesSettingKey = 'copilot.chat.nextEdits.hasEnabledNesInSettings'; - const enableEnhancedNotebookNES = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.UseAlternativeNESNotebookFormat, _experimentationService) || this._configurationService.getExperimentBasedConfig(ConfigKey.UseAlternativeNESNotebookFormat, _experimentationService); + const enableEnhancedNotebookNES = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.UseAlternativeNESNotebookFormat, _experimentationService) || this._configurationService.getExperimentBasedConfig(ConfigKey.UseAlternativeNESNotebookFormat, _experimentationService); const unificationState = unificationStateObservable(this); commands.executeCommand('setContext', useEnhancedNotebookNESContextKey, enableEnhancedNotebookNES); diff --git a/src/extension/inlineEdits/vscode-node/parts/vscodeWorkspace.ts b/src/extension/inlineEdits/vscode-node/parts/vscodeWorkspace.ts index 5d21aa8054..a29bd32bfc 100644 --- a/src/extension/inlineEdits/vscode-node/parts/vscodeWorkspace.ts +++ b/src/extension/inlineEdits/vscode-node/parts/vscodeWorkspace.ts @@ -44,7 +44,7 @@ export class VSCodeWorkspace extends ObservableWorkspace implements IDisposable private readonly _store = new DisposableStore(); private readonly _filter = this._instaService.createInstance(DocumentFilter); private get _useAlternativeNotebookFormat(): boolean { - return this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.UseAlternativeNESNotebookFormat, this._experimentationService) + return this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.UseAlternativeNESNotebookFormat, this._experimentationService) || this._configurationService.getExperimentBasedConfig(ConfigKey.UseAlternativeNESNotebookFormat, this._experimentationService); } private readonly _markdownNotebookCells = new Lazy(() => { diff --git a/src/extension/intents/node/agentIntent.ts b/src/extension/intents/node/agentIntent.ts index da3721a2c9..e54c5c0281 100644 --- a/src/extension/intents/node/agentIntent.ts +++ b/src/extension/intents/node/agentIntent.ts @@ -41,6 +41,7 @@ import { PromptRenderer } from '../../prompts/node/base/promptRenderer'; import { ICodeMapperService } from '../../prompts/node/codeMapper/codeMapperService'; import { TemporalContextStats } from '../../prompts/node/inline/temporalContext'; import { EditCodePrompt2 } from '../../prompts/node/panel/editCodePrompt2'; +import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt'; import { ToolResultMetadata } from '../../prompts/node/panel/toolCalling'; import { IEditToolLearningService } from '../../tools/common/editToolLearningService'; import { ContributedToolName, ToolName } from '../../tools/common/toolNames'; @@ -51,7 +52,6 @@ import { applyPatch5Description } from '../../tools/node/applyPatchTool'; import { addCacheBreakpoints } from './cacheBreakpoints'; import { EditCodeIntent, EditCodeIntentInvocation, EditCodeIntentInvocationOptions, mergeMetadata, toNewChatReferences } from './editCodeIntent'; import { getRequestedToolCallIterationLimit, IContinueOnErrorConfirmation } from './toolCallingLoop'; -import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt'; export const getAgentTools = (instaService: IInstantiationService, request: vscode.ChatRequest) => instaService.invokeFunction(async accessor => { @@ -115,7 +115,7 @@ export const getAgentTools = (instaService: IInstantiationService, request: vsco return undefined; }); - if (await modelSupportsSimplifiedApplyPatchInstructions(model) && configurationService.getExperimentBasedConfig(ConfigKey.Internal.Gpt5AlternativePatch, experimentationService)) { + if (await modelSupportsSimplifiedApplyPatchInstructions(model) && configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.Gpt5AlternativePatch, experimentationService)) { const ap = tools.findIndex(t => t.name === ToolName.ApplyPatch); if (ap !== -1) { tools[ap] = { ...tools[ap], description: applyPatch5Description }; @@ -187,7 +187,7 @@ export class AgentIntent extends EditCodeIntent { maxToolCallIterations: getRequestedToolCallIterationLimit(request) ?? this.configurationService.getNonExtensionConfig('chat.agent.maxRequests') ?? 200, // Fallback for simulation tests - temperature: this.configurationService.getConfig(ConfigKey.Internal.AgentTemperature) ?? 0, + temperature: this.configurationService.getConfig(ConfigKey.AdvancedExperimental.AgentTemperature) ?? 0, overrideRequestLocation: ChatLocation.Agent, hideRateLimitTimeEstimate: true }; @@ -249,10 +249,10 @@ export class AgentIntentInvocation extends EditCodeIntentInvocation implements I // Reserve extra space when tools are involved due to token counting issues const baseBudget = Math.min( - this.configurationService.getConfig(ConfigKey.Internal.SummarizeAgentConversationHistoryThreshold) ?? this.endpoint.modelMaxPromptTokens, + this.configurationService.getConfig(ConfigKey.AdvancedExperimental.SummarizeAgentConversationHistoryThreshold) ?? this.endpoint.modelMaxPromptTokens, this.endpoint.modelMaxPromptTokens ); - const useTruncation = this.configurationService.getConfig(ConfigKey.Internal.UseResponsesApiTruncation); + const useTruncation = this.configurationService.getConfig(ConfigKey.AdvancedExperimental.UseResponsesApiTruncation); const safeBudget = useTruncation ? Number.MAX_SAFE_INTEGER : Math.floor((baseBudget - toolTokens) * 0.85); diff --git a/src/extension/intents/node/askAgentIntent.ts b/src/extension/intents/node/askAgentIntent.ts index 04ff639095..59fc60f86f 100644 --- a/src/extension/intents/node/askAgentIntent.ts +++ b/src/extension/intents/node/askAgentIntent.ts @@ -64,7 +64,7 @@ export class AskAgentIntent implements IIntent { private getIntentHandlerOptions(request: vscode.ChatRequest): IDefaultIntentRequestHandlerOptions | undefined { return { maxToolCallIterations: getRequestedToolCallIterationLimit(request) ?? this.configurationService.getNonExtensionConfig('chat.agent.maxRequests') ?? 15, - temperature: this.configurationService.getConfig(ConfigKey.Internal.AgentTemperature) ?? 0, + temperature: this.configurationService.getConfig(ConfigKey.AdvancedExperimental.AgentTemperature) ?? 0, overrideRequestLocation: ChatLocation.EditingSession, }; } diff --git a/src/extension/intents/node/editCodeIntent.ts b/src/extension/intents/node/editCodeIntent.ts index 421e0f06fd..b760ac2a3c 100644 --- a/src/extension/intents/node/editCodeIntent.ts +++ b/src/extension/intents/node/editCodeIntent.ts @@ -102,7 +102,7 @@ export class EditCodeIntent implements IIntent { private async _handleCodesearch(conversation: Conversation, request: vscode.ChatRequest, location: ChatLocation, stream: vscode.ChatResponseStream, token: CancellationToken, documentContext: IDocumentContext | undefined, chatTelemetry: ChatTelemetryBuilder): Promise<{ request: vscode.ChatRequest; conversation: Conversation }> { const foundReferences: vscode.ChatPromptReference[] = []; - if ((this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.Internal.CodeSearchAgentEnabled)) && request.toolReferences.find((r) => r.name === CodebaseTool.toolName && !isDirectorySemanticSearch(r))) { + if ((this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CodeSearchAgentEnabled)) && request.toolReferences.find((r) => r.name === CodebaseTool.toolName && !isDirectorySemanticSearch(r))) { const latestTurn = conversation.getLatestTurn(); diff --git a/src/extension/intents/node/editCodeIntent2.ts b/src/extension/intents/node/editCodeIntent2.ts index eec7a99e1a..6ef041e6d4 100644 --- a/src/extension/intents/node/editCodeIntent2.ts +++ b/src/extension/intents/node/editCodeIntent2.ts @@ -25,12 +25,12 @@ import { IDefaultIntentRequestHandlerOptions } from '../../prompt/node/defaultIn import { IIntent, IntentLinkificationOptions } from '../../prompt/node/intents'; import { ICodeMapperService } from '../../prompts/node/codeMapper/codeMapperService'; import { EditCodePrompt2 } from '../../prompts/node/panel/editCodePrompt2'; +import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt'; import { ToolName } from '../../tools/common/toolNames'; import { IToolsService } from '../../tools/common/toolsService'; import { AgentIntentInvocation } from './agentIntent'; import { EditCodeIntent, EditCodeIntentOptions } from './editCodeIntent'; import { getRequestedToolCallIterationLimit } from './toolCallingLoop'; -import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt'; const getTools = (instaService: IInstantiationService, request: vscode.ChatRequest): Promise => @@ -81,7 +81,7 @@ export class EditCode2Intent extends EditCodeIntent { protected override getIntentHandlerOptions(request: vscode.ChatRequest): IDefaultIntentRequestHandlerOptions | undefined { return { maxToolCallIterations: getRequestedToolCallIterationLimit(request) ?? this.configurationService.getNonExtensionConfig('chat.agent.maxRequests') ?? 15, - temperature: this.configurationService.getConfig(ConfigKey.Internal.AgentTemperature) ?? 0, + temperature: this.configurationService.getConfig(ConfigKey.AdvancedExperimental.AgentTemperature) ?? 0, overrideRequestLocation: ChatLocation.EditingSession, }; } diff --git a/src/extension/intents/node/notebookEditorIntent.ts b/src/extension/intents/node/notebookEditorIntent.ts index 418db123f8..19e15eb510 100644 --- a/src/extension/intents/node/notebookEditorIntent.ts +++ b/src/extension/intents/node/notebookEditorIntent.ts @@ -72,7 +72,7 @@ export class NotebookEditorIntent extends EditCodeIntent { protected override getIntentHandlerOptions(request: vscode.ChatRequest): IDefaultIntentRequestHandlerOptions | undefined { return { maxToolCallIterations: getRequestedToolCallIterationLimit(request) ?? this.configurationService.getNonExtensionConfig('chat.agent.maxRequests') ?? 15, - temperature: this.configurationService.getConfig(ConfigKey.Internal.AgentTemperature) ?? 0, + temperature: this.configurationService.getConfig(ConfigKey.AdvancedExperimental.AgentTemperature) ?? 0, overrideRequestLocation: ChatLocation.Notebook, }; } diff --git a/src/extension/onboardDebug/node/debuggableCommandIdentifier.ts b/src/extension/onboardDebug/node/debuggableCommandIdentifier.ts index b098fe3d3e..951a7566a2 100644 --- a/src/extension/onboardDebug/node/debuggableCommandIdentifier.ts +++ b/src/extension/onboardDebug/node/debuggableCommandIdentifier.ts @@ -130,7 +130,7 @@ export class DebuggableCommandIdentifier extends Disposable implements IDebuggab } private getSpecificTreatment(command: string): boolean | undefined { - const patterns = this.configurationService.getConfig(ConfigKey.Internal.TerminalToDebuggerPatterns); + const patterns = this.configurationService.getConfig(ConfigKey.AdvancedExperimental.TerminalToDebuggerPatterns); for (const pattern of patterns) { if (pattern.startsWith('!') && this.commandIncludes(command, pattern)) { return false; diff --git a/src/extension/onboardDebug/test/node/debuggableCommandIdentifier.spec.ts b/src/extension/onboardDebug/test/node/debuggableCommandIdentifier.spec.ts index 50910d553b..26a6d880a8 100644 --- a/src/extension/onboardDebug/test/node/debuggableCommandIdentifier.spec.ts +++ b/src/extension/onboardDebug/test/node/debuggableCommandIdentifier.spec.ts @@ -103,13 +103,13 @@ describe('DebuggableCommandIdentifier', () => { }); it('returns treatment value 1', async () => { - accessor.get(IConfigurationService).setConfig(ConfigKey.Internal.TerminalToDebuggerPatterns, ['othert']); + accessor.get(IConfigurationService).setConfig(ConfigKey.AdvancedExperimental.TerminalToDebuggerPatterns, ['othert']); const result = await debuggableCommandIdentifier.isDebuggable(undefined, 'othert hello', CancellationToken.None); expect(result).to.be.true; }); it('return treatment value 2', async () => { - accessor.get(IConfigurationService).setConfig(ConfigKey.Internal.TerminalToDebuggerPatterns, ['!mytool']); + accessor.get(IConfigurationService).setConfig(ConfigKey.AdvancedExperimental.TerminalToDebuggerPatterns, ['!mytool']); const result = await debuggableCommandIdentifier.isDebuggable(undefined, 'mytool hello', CancellationToken.None); expect(result).to.be.false; }); diff --git a/src/extension/prompt/vscode-node/endpointProviderImpl.ts b/src/extension/prompt/vscode-node/endpointProviderImpl.ts index 4affffcb96..bc0b3f64da 100644 --- a/src/extension/prompt/vscode-node/endpointProviderImpl.ts +++ b/src/extension/prompt/vscode-node/endpointProviderImpl.ts @@ -70,7 +70,7 @@ export class ProductionEndpointProvider implements IEndpointProvider { } private get _overridenChatModel(): string | undefined { - return this._configService.getConfig(ConfigKey.Internal.DebugOverrideChatEngine); + return this._configService.getConfig(ConfigKey.AdvancedExperimental.DebugOverrideChatEngine); } private getOrCreateChatEndpointInstance(modelMetadata: IChatModelInformation): IChatEndpoint { diff --git a/src/extension/promptFileContext/vscode-node/promptFileContextService.ts b/src/extension/promptFileContext/vscode-node/promptFileContextService.ts index e8ff55f1f8..630d5a4f4a 100644 --- a/src/extension/promptFileContext/vscode-node/promptFileContextService.ts +++ b/src/extension/promptFileContext/vscode-node/promptFileContextService.ts @@ -32,7 +32,7 @@ export class PromptFileContextContribution extends Disposable { @ILanguageContextProviderService private readonly languageContextProviderService: ILanguageContextProviderService, ) { super(); - this._enableCompletionContext = configurationService.getExperimentBasedConfigObservable(ConfigKey.Internal.PromptFileContext, experimentationService); + this._enableCompletionContext = configurationService.getExperimentBasedConfigObservable(ConfigKey.AdvancedExperimentalExperiments.PromptFileContext, experimentationService); this._register(autorun(reader => { if (this._enableCompletionContext.read(reader)) { this.registration = this.register(); diff --git a/src/extension/prompts/node/agent/agentPrompt.tsx b/src/extension/prompts/node/agent/agentPrompt.tsx index a2a0904ceb..ab53a5020c 100644 --- a/src/extension/prompts/node/agent/agentPrompt.tsx +++ b/src/extension/prompts/node/agent/agentPrompt.tsx @@ -88,7 +88,7 @@ export class AgentPrompt extends PromptElement { async render(state: void, sizing: PromptSizing) { const instructions = await this.getInstructions(); - const omitBaseAgentInstructions = this.configurationService.getConfig(ConfigKey.Internal.OmitBaseAgentInstructions); + const omitBaseAgentInstructions = this.configurationService.getConfig(ConfigKey.AdvancedExperimental.OmitBaseAgentInstructions); const baseAgentInstructions = <> You are an expert AI programming assistant, working with a user in the VS Code editor.
diff --git a/src/extension/prompts/node/agent/defaultAgentInstructions.tsx b/src/extension/prompts/node/agent/defaultAgentInstructions.tsx index 44d3e05f73..0715329fe0 100644 --- a/src/extension/prompts/node/agent/defaultAgentInstructions.tsx +++ b/src/extension/prompts/node/agent/defaultAgentInstructions.tsx @@ -6,6 +6,7 @@ import { BasePromptElementProps, PromptElement, PromptSizing } from '@vscode/prompt-tsx'; import type { LanguageModelToolInformation } from 'vscode'; import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; +import { isHiddenModelB } from '../../../../platform/endpoint/common/chatModelCapabilities'; import { IExperimentationService } from '../../../../platform/telemetry/common/nullExperimentationService'; import { LanguageModelToolMCPSource } from '../../../../vscodeTypes'; import { ToolName } from '../../../tools/common/toolNames'; @@ -16,7 +17,6 @@ import { Tag } from '../base/tag'; import { CodeBlockFormattingRules, EXISTING_CODE_MARKER } from '../panel/codeBlockFormattingRules'; import { MathIntegrationRules } from '../panel/editorIntegrationRules'; import { KeepGoingReminder } from './agentPrompt'; -import { isHiddenModelB } from '../../../../platform/endpoint/common/chatModelCapabilities'; // Types and interfaces for reusable components interface ToolCapabilities extends Partial> { @@ -402,7 +402,7 @@ export class ApplyPatchInstructions extends PromptElement To edit files in the workspace, use the {ToolName.ApplyPatch} tool. If you have issues with it, you should first try to fix your patch and continue using {ToolName.ApplyPatch}. {this.props.tools[ToolName.EditFile] && <>If you are stuck, you can fall back on the {ToolName.EditFile} tool, but {ToolName.ApplyPatch} is much faster and is the preferred tool.}
diff --git a/src/extension/prompts/node/agent/summarizedConversationHistory.tsx b/src/extension/prompts/node/agent/summarizedConversationHistory.tsx index 11a6937f16..8dfb3e9708 100644 --- a/src/extension/prompts/node/agent/summarizedConversationHistory.tsx +++ b/src/extension/prompts/node/agent/summarizedConversationHistory.tsx @@ -416,7 +416,7 @@ class ConversationHistorySummarizer { } private async getSummaryWithFallback(propsInfo: ISummarizedConversationHistoryInfo): Promise> { - const forceMode = this.configurationService.getConfig(ConfigKey.Internal.AgentHistorySummarizationMode); + const forceMode = this.configurationService.getConfig(ConfigKey.AdvancedExperimental.AgentHistorySummarizationMode); if (forceMode === SummaryMode.Simple) { return await this.getSummary(SummaryMode.Simple, propsInfo); } else { @@ -438,7 +438,7 @@ class ConversationHistorySummarizer { private async getSummary(mode: SummaryMode, propsInfo: ISummarizedConversationHistoryInfo): Promise> { const stopwatch = new StopWatch(false); - const forceGpt41 = this.configurationService.getExperimentBasedConfig(ConfigKey.Internal.AgentHistorySummarizationForceGpt41, this.experimentationService); + const forceGpt41 = this.configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.AgentHistorySummarizationForceGpt41, this.experimentationService); const gpt41Endpoint = await this.endpointProvider.getChatEndpoint('gpt-4.1'); const endpoint = forceGpt41 && (gpt41Endpoint.modelMaxPromptTokens >= this.props.endpoint.modelMaxPromptTokens) ? gpt41Endpoint : @@ -446,7 +446,7 @@ class ConversationHistorySummarizer { let summarizationPrompt: ChatMessage[]; const associatedRequestId = this.props.promptContext.conversation?.getLatestTurn().id; - const promptCacheMode = this.configurationService.getExperimentBasedConfig(ConfigKey.Internal.AgentHistorySummarizationWithPromptCache, this.experimentationService); + const promptCacheMode = this.configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.AgentHistorySummarizationWithPromptCache, this.experimentationService); try { if (mode === SummaryMode.Full && promptCacheMode) { const props: AgentPromptProps = { diff --git a/src/extension/prompts/node/agent/test/agentPrompt.spec.tsx b/src/extension/prompts/node/agent/test/agentPrompt.spec.tsx index bff430d525..d66611a05d 100644 --- a/src/extension/prompts/node/agent/test/agentPrompt.spec.tsx +++ b/src/extension/prompts/node/agent/test/agentPrompt.spec.tsx @@ -260,7 +260,7 @@ import { AgentPrompt, AgentPromptProps } from '../agentPrompt'; }); test('omit base agent instructions', async () => { - accessor.get(IConfigurationService).setConfig(ConfigKey.Internal.OmitBaseAgentInstructions, true); + accessor.get(IConfigurationService).setConfig(ConfigKey.AdvancedExperimental.OmitBaseAgentInstructions, true); expect(await agentPromptToString(accessor, { chatVariables: new ChatVariablesCollection(), history: [], diff --git a/src/extension/prompts/node/codeMapper/codeMapper.ts b/src/extension/prompts/node/codeMapper/codeMapper.ts index 81b56065a0..1e266e7432 100644 --- a/src/extension/prompts/node/codeMapper/codeMapper.ts +++ b/src/extension/prompts/node/codeMapper/codeMapper.ts @@ -314,7 +314,7 @@ export class CodeMapper { this.gpt4oProxyEndpoint = this.experimentationService.hasTreatments().then(() => this.instantiationService.createInstance(Proxy4oEndpoint)); this.shortIAEndpoint = this.experimentationService.hasTreatments().then(() => this.instantiationService.createInstance(ProxyInstantApplyShortEndpoint)); - this.shortContextLimit = configurationService.getExperimentBasedConfig(ConfigKey.Internal.InstantApplyShortContextLimit, experimentationService) ?? 8000; + this.shortContextLimit = configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.InstantApplyShortContextLimit, experimentationService) ?? 8000; } public async mapCode(request: ICodeMapperRequestInput, resultStream: MappedEditsResponseStream, telemetryInfo: ICodeMapperTelemetryInfo | undefined, token: CancellationToken): Promise { diff --git a/src/extension/prompts/node/inline/inlineChatEditCodePrompt.tsx b/src/extension/prompts/node/inline/inlineChatEditCodePrompt.tsx index c6c2637299..a308ace9f5 100644 --- a/src/extension/prompts/node/inline/inlineChatEditCodePrompt.tsx +++ b/src/extension/prompts/node/inline/inlineChatEditCodePrompt.tsx @@ -61,7 +61,7 @@ export class InlineChatEditCodePrompt extends PromptElement { {hasFilesInWorkingSet ? <>The user has a request for modifying one or more files.
: <>If the user asks a question, then answer it.
- If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.Internal.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".
+ If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".
The only exception is if you need to create new files. In that case, follow the following instructions.
} 1. Please come up with a solution that you first describe step-by-step.
2. Group your changes by file. Use the file path as the header.
@@ -303,7 +303,7 @@ export class EditCodeUserMessage extends PromptElement { async render(state: void, sizing: PromptSizing) { const { query, chatVariables, workingSet } = this.props.promptContext; - const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.ProjectLabelsChat, this.experimentationService); + const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsChat, this.experimentationService); return ( <> diff --git a/src/extension/prompts/node/panel/editCodePrompt2.tsx b/src/extension/prompts/node/panel/editCodePrompt2.tsx index 47e73c530f..23239a3599 100644 --- a/src/extension/prompts/node/panel/editCodePrompt2.tsx +++ b/src/extension/prompts/node/panel/editCodePrompt2.tsx @@ -40,7 +40,7 @@ export class EditCodePrompt2 extends PromptElement { {hasFilesInWorkingSet ? <>The user has a request for modifying one or more files. : <>If the user asks a question, then answer it.
- If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.Internal.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".
+ If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".
The only exception is if you need to create new files. In that case, follow the following instructions.} ; const hasReplaceStringTool = this.toolsService.getTool(ToolName.ReplaceString) !== undefined; @@ -135,7 +135,7 @@ class EditCode2UserMessage extends PromptElement { async render(state: void, sizing: PromptSizing) { const { query, chatVariables } = this.props.promptContext; - const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.ProjectLabelsChat, this.experimentationService); + const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsChat, this.experimentationService); const hasReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.ReplaceString); const hasEditFileTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.EditFile); const hasMultiReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.MultiReplaceString); diff --git a/src/extension/prompts/node/panel/notebookInlinePrompt.tsx b/src/extension/prompts/node/panel/notebookInlinePrompt.tsx index 5593a761c5..a9c748dca9 100644 --- a/src/extension/prompts/node/panel/notebookInlinePrompt.tsx +++ b/src/extension/prompts/node/panel/notebookInlinePrompt.tsx @@ -37,7 +37,7 @@ export class NotebookInlinePrompt extends PromptElement { {hasFilesInWorkingSet ? <>The user has a request for modifying one or more files. : <>If the user asks a question, then answer it.
- If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.Internal.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".
+ If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.AdvancedExperimental.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".
The only exception is if you need to create new files. In that case, follow the following instructions.} ; const instructions = @@ -90,7 +90,7 @@ class EditCode2UserMessage extends PromptElement { async render(state: void, sizing: PromptSizing) { const { query, chatVariables } = this.props.promptContext; - const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.ProjectLabelsChat, this.experimentationService); + const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsChat, this.experimentationService); const hasReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.ReplaceString); const hasEditFileTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.EditFile); const hasMultiReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.MultiReplaceString); diff --git a/src/extension/prompts/node/panel/panelChatBasePrompt.tsx b/src/extension/prompts/node/panel/panelChatBasePrompt.tsx index 79c4559a4d..534b678d66 100644 --- a/src/extension/prompts/node/panel/panelChatBasePrompt.tsx +++ b/src/extension/prompts/node/panel/panelChatBasePrompt.tsx @@ -38,7 +38,7 @@ export class PanelChatBasePrompt extends PromptElement async render(state: void, sizing: PromptSizing) { const { query, history, chatVariables, } = this.props.promptContext; - const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.ProjectLabelsChat, this.experimentationService); + const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsChat, this.experimentationService); const operatingSystem = this.envService.OS; return ( diff --git a/src/extension/prompts/node/panel/preferences.tsx b/src/extension/prompts/node/panel/preferences.tsx index 0a8d8baea1..3cb2ab4bbf 100644 --- a/src/extension/prompts/node/panel/preferences.tsx +++ b/src/extension/prompts/node/panel/preferences.tsx @@ -22,7 +22,7 @@ export class UserPreferences extends PromptElement { super(props); } override async render(state: void, sizing: PromptSizing) { - if (!this.configurationService.getConfig(ConfigKey.Internal.EnableUserPreferences)) { + if (!this.configurationService.getConfig(ConfigKey.AdvancedExperimental.EnableUserPreferences)) { return undefined; } diff --git a/src/extension/prompts/node/test/temporalContext.spec.ts b/src/extension/prompts/node/test/temporalContext.spec.ts index 9a86427e03..80d847f135 100644 --- a/src/extension/prompts/node/test/temporalContext.spec.ts +++ b/src/extension/prompts/node/test/temporalContext.spec.ts @@ -122,7 +122,7 @@ suite('summarizeTemporalContext', () => { test('prefer same lang', async () => { - configService.setConfig(ConfigKey.Internal.TemporalContextPreferSameLang as any, true); + configService.setConfig(ConfigKey.AdvancedExperimentalExperiments.TemporalContextPreferSameLang as any, true); const docActions = await makeSampleDoc('tempo-actions.ts'); const docActions2 = await makeSampleDoc('tempo-actions.html', 'html'); @@ -143,7 +143,7 @@ suite('summarizeTemporalContext', () => { await expect(result.get(docActions.uri.toString())?.projectedDoc?.text).toMatchFileSnapshot(docActions.uri.fsPath + '.3.tempo-summarized'); await expect(result.get(docActions2.uri.toString())?.projectedDoc?.text).toMatchFileSnapshot(docActions2.uri.fsPath + '.3.tempo-summarized'); - configService.setConfig(ConfigKey.Internal.TemporalContextPreferSameLang as any, false); + configService.setConfig(ConfigKey.AdvancedExperimentalExperiments.TemporalContextPreferSameLang as any, false); }); diff --git a/src/extension/relatedFiles/node/gitRelatedFilesProvider.ts b/src/extension/relatedFiles/node/gitRelatedFilesProvider.ts index 113cd759d6..ccb245a05e 100644 --- a/src/extension/relatedFiles/node/gitRelatedFilesProvider.ts +++ b/src/extension/relatedFiles/node/gitRelatedFilesProvider.ts @@ -39,7 +39,7 @@ export class GitRelatedFilesProvider extends Disposable implements vscode.ChatRe ) { super(); - if (this._configurationService.getConfig(ConfigKey.Internal.GitHistoryRelatedFilesUsingEmbeddings)) { + if (this._configurationService.getConfig(ConfigKey.AdvancedExperimental.GitHistoryRelatedFilesUsingEmbeddings)) { // Index the latest 200 commits in the background // TODO@joyceerhl reindex incrementally when repository state changes // TODO@joyceerhl use only the changes from main branch? @@ -69,7 +69,7 @@ export class GitRelatedFilesProvider extends Disposable implements vscode.ChatRe return this.getCommitsForPromptWithoutFiles(chatRequest, token); } - if (this._configurationService.getConfig(ConfigKey.Internal.GitHistoryRelatedFilesUsingEmbeddings)) { + if (this._configurationService.getConfig(ConfigKey.AdvancedExperimental.GitHistoryRelatedFilesUsingEmbeddings)) { return this.computeRelevantCommits(chatRequest, token); } diff --git a/src/extension/tools/common/virtualTools/virtualToolGrouper.ts b/src/extension/tools/common/virtualTools/virtualToolGrouper.ts index c7646173d4..776ce470ff 100644 --- a/src/extension/tools/common/virtualTools/virtualToolGrouper.ts +++ b/src/extension/tools/common/virtualTools/virtualToolGrouper.ts @@ -50,7 +50,7 @@ export class VirtualToolGrouper implements IToolCategorization { * Determines if built-in tool grouping should be triggered based on configuration and tool count */ private shouldTriggerBuiltInGrouping(tools: LanguageModelToolInformation[]): boolean { - const defaultToolGroupingEnabled = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.DefaultToolsGrouped, this._expService); + const defaultToolGroupingEnabled = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.DefaultToolsGrouped, this._expService); return tools.length > Constant.START_BUILTIN_GROUPING_AFTER_TOOL_COUNT && defaultToolGroupingEnabled; } diff --git a/src/extension/workspaceRecorder/vscode-node/workspaceRecorderFeature.ts b/src/extension/workspaceRecorder/vscode-node/workspaceRecorderFeature.ts index c57147f16f..a6576dfdd7 100644 --- a/src/extension/workspaceRecorder/vscode-node/workspaceRecorderFeature.ts +++ b/src/extension/workspaceRecorder/vscode-node/workspaceRecorderFeature.ts @@ -31,7 +31,7 @@ import { WorkspaceRecorder } from './workspaceRecorder'; export class WorkspaceRecorderFeature extends Disposable { private readonly _gitApi = observableFromEvent(this, (listener) => this._gitExtensionService.onDidChange(listener), () => this._gitExtensionService.getExtensionApi()); - private readonly _workspaceRecordingEnabled = this._configurationService.getConfigObservable(ConfigKey.Internal.WorkspaceRecordingEnabled); + private readonly _workspaceRecordingEnabled = this._configurationService.getConfigObservable(ConfigKey.AdvancedExperimental.WorkspaceRecordingEnabled); constructor( @IVSCodeExtensionContext private readonly _vscodeExtensionContext: IVSCodeExtensionContext, diff --git a/src/extension/xtab/node/xtabProvider.ts b/src/extension/xtab/node/xtabProvider.ts index 1b163dfed8..ec879c2a28 100644 --- a/src/extension/xtab/node/xtabProvider.ts +++ b/src/extension/xtab/node/xtabProvider.ts @@ -1132,7 +1132,7 @@ export class XtabProvider implements IStatelessNextEditProvider { const systemMessage = 'Your task is to predict the next line number in the current file where the developer is most likely to make their next edit, using the provided context.'; - const maxTokens = this.configService.getExperimentBasedConfig(ConfigKey.Internal.InlineEditsNextCursorPredictionCurrentFileMaxTokens, this.expService); + const maxTokens = this.configService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.InlineEditsNextCursorPredictionCurrentFileMaxTokens, this.expService); const currentFileContentR = this.constructTaggedFile( promptPieces.currentDocument, diff --git a/src/platform/configuration/common/configurationService.ts b/src/platform/configuration/common/configurationService.ts index 37c7d2833a..4e24fce639 100644 --- a/src/platform/configuration/common/configurationService.ts +++ b/src/platform/configuration/common/configurationService.ts @@ -363,6 +363,11 @@ export interface BaseConfig { */ readonly id: string; + /** + * The old key as it appears in settings.json minus the "github.copilot." prefix. + */ + readonly oldId?: string; + /** * This setting is present in package.json and is visible to the general public. */ @@ -374,6 +379,11 @@ export interface BaseConfig { */ readonly fullyQualifiedId: string; + /** + * The fully qualified old id, e.g. "github.copilot.advanced.debug.overrideProxyUrl". + */ + readonly fullyQualifiedOldId?: string | undefined; + /** * The `X` in `github.copilot.advanced.X` settings. */ @@ -398,17 +408,11 @@ export const enum ConfigType { } export interface ConfigOptions { + readonly oldKey?: string; readonly internal?: boolean; readonly valueIgnoredForExternals?: boolean; } -/** - * Indicates that a setting is hidden and not registered in package.json - */ -const INTERNAL: ConfigOptions = { - internal: true -}; - /** * Indicates that a setting can not be configured by external users */ @@ -444,6 +448,7 @@ function getPackageJsonDefaults(): Map { function toBaseConfig(key: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options: ConfigOptions | undefined): BaseConfig { const fullyQualifiedId = `${CopilotConfigPrefix}.${key}`; + const fullyQualifiedOldId = options?.oldKey ? `${CopilotConfigPrefix}.${options.oldKey}` : undefined; const packageJsonDefaults = getPackageJsonDefaults(); const isPublic = packageJsonDefaults.has(fullyQualifiedId); const packageJsonDefaultValue = packageJsonDefaults.get(fullyQualifiedId); @@ -476,7 +481,7 @@ function toBaseConfig(key: string, defaultValue: T | DefaultValueWithTeamValu } } const advancedSubKey = fullyQualifiedId.startsWith('github.copilot.advanced.') ? fullyQualifiedId.substring('github.copilot.advanced.'.length) : undefined; - return { id: key, isPublic, fullyQualifiedId, advancedSubKey, defaultValue, options }; + return { id: key, oldId: options?.oldKey, isPublic, fullyQualifiedId, fullyQualifiedOldId, advancedSubKey, defaultValue, options }; } class ConfigRegistry { @@ -528,20 +533,6 @@ function defineSetting(key: string, defaultValue: T | DefaultValueWithTeamVal return value; } -function defineAndMigrateSetting(oldKey: string, newKey: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions): Config { - const value = defineSetting(newKey, defaultValue, options); - ConfigurationMigrationRegistry.registerConfigurationMigrations([{ - key: `${CopilotConfigPrefix}.${oldKey}`, - migrateFn: async (migrationValue: any) => { - return [ - [`${CopilotConfigPrefix}.${newKey}`, { value: migrationValue }], - [`${CopilotConfigPrefix}.${oldKey}`, { value: undefined }] - ]; - } - }]); - return value; -} - /** * Will define a setting which will be backed by an experiment. The experiment variable will be: * ``` @@ -551,7 +542,7 @@ function defineAndMigrateSetting(oldKey: string, newKey: string, defaultValue * config.github.copilot.chat.advanced.inlineEdits.internalRollout * ``` */ -export function defineExpSetting(key: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions, expOptions?: { experimentName?: string }): ExperimentBasedConfig { +function defineExpSetting(key: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions, expOptions?: { experimentName?: string }): ExperimentBasedConfig { const value: ExperimentBasedConfig = { ...toBaseConfig(key, defaultValue, options), configType: ConfigType.ExperimentBased, experimentName: expOptions?.experimentName }; if (value.advancedSubKey) { // This is a `github.copilot.advanced.*` setting @@ -561,8 +552,7 @@ export function defineExpSetting(key: strin return value; } -export function defineAndMigrateExpSetting(oldKey: string, newKey: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions, expOptions?: { experimentName?: string }): ExperimentBasedConfig { - const value = defineExpSetting(newKey, defaultValue, options, expOptions); +function migrateSetting(newKey: string, oldKey: string): void { ConfigurationMigrationRegistry.registerConfigurationMigrations([{ key: `${CopilotConfigPrefix}.${oldKey}`, migrateFn: async (migrationValue: any) => { @@ -572,7 +562,16 @@ export function defineAndMigrateExpSetting( ]; } }]); - return value; +} + +function defineAndMigrateSetting(oldKey: string, newKey: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions): Config { + migrateSetting(newKey, oldKey); + return defineSetting(newKey, defaultValue, { ...options, oldKey }); +} + +function defineAndMigrateExpSetting(oldKey: string, newKey: string, defaultValue: T | DefaultValueWithTeamValue | DefaultValueWithTeamAndInternalValue, options?: ConfigOptions, expOptions?: { experimentName?: string }): ExperimentBasedConfig { + migrateSetting(newKey, oldKey); + return defineExpSetting(newKey, defaultValue, { ...options, oldKey }, expOptions); } // Max CAPI tool count limit @@ -631,8 +630,8 @@ export namespace ConfigKey { */ export namespace Shared { /** Allows for overriding the base domain we use for making requests to the CAPI. This helps CAPI devs develop against a local instance. */ - export const DebugOverrideProxyUrl = defineSetting('advanced.debug.overrideProxyUrl', undefined, INTERNAL); - export const DebugOverrideCAPIUrl = defineSetting('advanced.debug.overrideCapiUrl', undefined, INTERNAL); + export const DebugOverrideProxyUrl = defineSetting('advanced.debug.overrideProxyUrl', undefined); + export const DebugOverrideCAPIUrl = defineSetting('advanced.debug.overrideCapiUrl', undefined); export const DebugUseNodeFetchFetcher = defineSetting('advanced.debug.useNodeFetchFetcher', true); export const DebugUseNodeFetcher = defineSetting('advanced.debug.useNodeFetcher', false); export const DebugUseElectronFetcher = defineSetting('advanced.debug.useElectronFetcher', true); @@ -641,32 +640,49 @@ export namespace ConfigKey { } /** - * Internal and debugging settings that should be hidden from users. - * - * Features should only be in this list temporarily, moving on to experimental to be accessible to early adopters. - */ - export namespace Internal { + * Advanced experimental settings that are available for all users to configure. + * These should only be in this list temporarily. Either should be made stable or removed. + */ + export namespace AdvancedExperimental { /** Allows forcing a particular model. * Note: this should not be used while self-hosting because it might lead to * a fundamental different experience compared to our end-users. - */ + */ export const DebugOverrideChatEngine = defineAndMigrateSetting('chat.advanced.debug.overrideChatEngine', 'chat.debug.overrideChatEngine', undefined); - /** Allows forcing a particular context window size. - * This setting doesn't validate values so large windows may not be supported by the model. - * Note: this should not be used while self-hosting because it might lead to - * a fundamental different experience compared to our end-users. - */ - export const DebugOverrideChatMaxTokenNum = defineSetting('chat.advanced.debug.overrideChatMaxTokenNum', 0, INTERNAL_RESTRICTED); - /** Allow reporting issue when clicking on the Unhelpful button - * Requires a window reload to take effect - */ - export const DebugReportFeedback = defineSetting('chat.advanced.debug.reportFeedback', { defaultValue: false, teamDefaultValue: true }, INTERNAL_RESTRICTED); - export const DebugCollectFetcherTelemetry = defineExpSetting('chat.advanced.debug.collectFetcherTelemetry', true, INTERNAL_RESTRICTED); - export const DebugExpUseNodeFetchFetcher = defineExpSetting('chat.advanced.debug.useNodeFetchFetcher', undefined, INTERNAL_RESTRICTED); - export const DebugExpUseNodeFetcher = defineExpSetting('chat.advanced.debug.useNodeFetcher', undefined, INTERNAL_RESTRICTED); - export const DebugExpUseElectronFetcher = defineExpSetting('chat.advanced.debug.useElectronFetcher', undefined, INTERNAL_RESTRICTED); - export const GitHistoryRelatedFilesUsingEmbeddings = defineSetting('chat.advanced.suggestRelatedFilesFromGitHistory.useEmbeddings', false); + export const WorkspacePrototypeAdoCodeSearchEndpointOverride = defineAndMigrateSetting('chat.advanced.workspace.prototypeAdoCodeSearchEndpointOverride', 'chat.workspace.prototypeAdoCodeSearchEndpointOverride', ''); + export const FeedbackOnChange = defineAndMigrateSetting('chat.advanced.feedback.onChange', 'chat.feedback.onChange', false); + export const ReviewIntent = defineAndMigrateSetting('chat.advanced.review.intent', 'chat.review.intent', false); + /** Enable the new notebook priorities experiment */ + export const NotebookSummaryExperimentEnabled = defineAndMigrateSetting('chat.advanced.notebook.summaryExperimentEnabled', 'chat.notebook.summaryExperimentEnabled', false); + /** Enable filtering variables by cell document symbols */ + export const NotebookVariableFilteringEnabled = defineAndMigrateSetting('chat.advanced.notebook.variableFilteringEnabled', 'chat.notebook.variableFilteringEnabled', false); + export const TerminalToDebuggerPatterns = defineAndMigrateSetting('chat.advanced.debugTerminalCommandPatterns', 'chat.debugTerminalCommandPatterns', []); + export const WorkspaceRecordingEnabled = defineAndMigrateSetting('chat.advanced.localWorkspaceRecording.enabled', 'chat.localWorkspaceRecording.enabled', false); + export const EditRecordingEnabled = defineAndMigrateSetting('chat.advanced.editRecording.enabled', 'chat.editRecording.enabled', false); + export const CodeSearchAgentEnabled = defineAndMigrateSetting('chat.advanced.codesearch.agent.enabled', 'chat.codesearch.agent.enabled', true); + export const AgentTemperature = defineAndMigrateSetting('chat.advanced.agent.temperature', 'chat.agent.temperature', undefined); + export const EnableUserPreferences = defineAndMigrateSetting('chat.advanced.enableUserPreferences', 'chat.enableUserPreferences', false); + export const SummarizeAgentConversationHistoryThreshold = defineAndMigrateSetting('chat.advanced.summarizeAgentConversationHistoryThreshold', 'chat.summarizeAgentConversationHistoryThreshold', undefined); + export const AgentHistorySummarizationMode = defineAndMigrateSetting('chat.advanced.agentHistorySummarizationMode', 'chat.agentHistorySummarizationMode', undefined); + export const UseResponsesApiTruncation = defineAndMigrateSetting('chat.advanced.useResponsesApiTruncation', 'chat.useResponsesApiTruncation', false); + export const OmitBaseAgentInstructions = defineAndMigrateSetting('chat.advanced.omitBaseAgentInstructions', 'chat.omitBaseAgentInstructions', false); + export const ClaudeCodeDebugEnabled = defineAndMigrateSetting('chat.advanced.claudeCode.debug', 'chat.claudeCode.debug', false); + export const CopilotCLIEnabled = defineAndMigrateSetting('chat.advanced.copilotCLI.enabled', 'chat.copilotCLI.enabled', true); + export const GitHistoryRelatedFilesUsingEmbeddings = defineAndMigrateSetting('chat.advanced.suggestRelatedFilesFromGitHistory.useEmbeddings', 'chat.suggestRelatedFilesFromGitHistory.useEmbeddings', false); + export const CLIIsolationEnabled = defineAndMigrateSetting('chat.cli.isolation.enabled', 'chat.advanced.cli.isolation.enabled', false); + export const CLIMCPServerEnabled = defineAndMigrateSetting('chat.cli.mcp.enabled', 'chat.advanced.cli.mcp.enabled', false); + // Unused + export const EditSourceTrackingShowDecorations = defineAndMigrateSetting('chat.advanced.editSourceTracking.showDecorations', 'chat.editSourceTracking.showDecorations', false); + export const EditSourceTrackingShowStatusBar = defineAndMigrateSetting('chat.advanced.editSourceTracking.showStatusBar', 'chat.editSourceTracking.showStatusBar', false); + export const EnableClaudeCodeAgent = defineAndMigrateSetting('chat.advanced.claudeCode.enabled', 'chat.claudeCode.enabled', false); + } + + /** + * Advanced experimental settings that are available for all users to configure and controlled by experiments. + * These should only be in this list temporarily. Either should be made stable or removed. + */ + export namespace AdvancedExperimentalExperiments { /** Uses new expanded project labels */ export const ProjectLabelsExpanded = defineAndMigrateExpSetting('chat.advanced.projectLabels.expanded', 'chat.projectLabels.expanded', false); /** Add project labels in default agent */ @@ -678,16 +694,46 @@ export namespace ConfigKey { export const WorkspaceEnableCodeSearch = defineAndMigrateExpSetting('chat.advanced.workspace.enableCodeSearch', 'chat.workspace.enableCodeSearch', true); export const WorkspaceEnableEmbeddingsSearch = defineAndMigrateExpSetting('chat.advanced.workspace.enableEmbeddingsSearch', 'chat.workspace.enableEmbeddingsSearch', true); export const WorkspacePreferredEmbeddingsModel = defineAndMigrateExpSetting('chat.advanced.workspace.preferredEmbeddingsModel', 'chat.workspace.preferredEmbeddingsModel', ''); - export const WorkspacePrototypeAdoCodeSearchEndpointOverride = defineAndMigrateSetting('chat.advanced.workspace.prototypeAdoCodeSearchEndpointOverride', 'chat.workspace.prototypeAdoCodeSearchEndpointOverride', ''); - export const FeedbackOnChange = defineAndMigrateSetting('chat.advanced.feedback.onChange', 'chat.feedback.onChange', false); - export const ReviewIntent = defineAndMigrateSetting('chat.advanced.review.intent', 'chat.review.intent', false); - /** Enable the new notebook priorities experiment */ - export const NotebookSummaryExperimentEnabled = defineAndMigrateSetting('chat.advanced.notebook.summaryExperimentEnabled', 'chat.notebook.summaryExperimentEnabled', false); - /** Enable filtering variables by cell document symbols */ - export const NotebookVariableFilteringEnabled = defineAndMigrateSetting('chat.advanced.notebook.variableFilteringEnabled', 'chat.notebook.variableFilteringEnabled', false); export const NotebookAlternativeDocumentFormat = defineAndMigrateExpSetting('chat.advanced.notebook.alternativeFormat', 'chat.notebook.alternativeFormat', AlternativeNotebookFormat.xml); export const UseAlternativeNESNotebookFormat = defineAndMigrateExpSetting('chat.advanced.notebook.alternativeNESFormat.enabled', 'chat.notebook.alternativeNESFormat.enabled', false); - export const TerminalToDebuggerPatterns = defineAndMigrateSetting('chat.advanced.debugTerminalCommandPatterns', 'chat.debugTerminalCommandPatterns', []); + /** Configure temporal context max age */ + export const TemporalContextMaxAge = defineAndMigrateExpSetting('chat.advanced.temporalContext.maxAge', 'chat.temporalContext.maxAge', 100); + export const TemporalContextPreferSameLang = defineAndMigrateExpSetting('chat.advanced.temporalContext.preferSameLang', 'chat.temporalContext.preferSameLang', false); + export const InstantApplyShortModelName = defineAndMigrateExpSetting('chat.advanced.instantApply.shortContextModelName', 'chat.instantApply.shortContextModelName', CHAT_MODEL.SHORT_INSTANT_APPLY); + export const InstantApplyShortContextLimit = defineAndMigrateExpSetting('chat.advanced.instantApply.shortContextLimit', 'chat.instantApply.shortContextLimit', 8000); + export const AgentHistorySummarizationWithPromptCache = defineAndMigrateExpSetting('chat.advanced.agentHistorySummarizationWithPromptCache', 'chat.agentHistorySummarizationWithPromptCache', false); + export const AgentHistorySummarizationForceGpt41 = defineAndMigrateExpSetting('chat.advanced.agentHistorySummarizationForceGpt41', 'chat.agentHistorySummarizationForceGpt41', false); + export const PromptFileContext = defineAndMigrateExpSetting('chat.advanced.promptFileContextProvider.enabled', 'chat.promptFileContextProvider.enabled', true); + export const DefaultToolsGrouped = defineAndMigrateExpSetting('chat.advanced.tools.defaultToolsGrouped', 'chat.tools.defaultToolsGrouped', false); + export const Gpt5AlternativePatch = defineAndMigrateExpSetting('chat.advanced.gpt5AlternativePatch', 'chat.gpt5AlternativePatch', false); + export const InlineEditsTriggerOnEditorChangeAfterSeconds = defineAndMigrateExpSetting('chat.advanced.inlineEdits.triggerOnEditorChangeAfterSeconds', 'chat.inlineEdits.triggerOnEditorChangeAfterSeconds', { defaultValue: undefined, teamDefaultValue: 10 }); + export const InlineEditsNextCursorPredictionDisplayLine = defineAndMigrateExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.displayLine', 'chat.inlineEdits.nextCursorPrediction.displayLine', true); + export const InlineEditsNextCursorPredictionCurrentFileMaxTokens = defineAndMigrateExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.currentFileMaxTokens', 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens', xtabPromptOptions.DEFAULT_OPTIONS.currentFile.maxTokens); + + // Unused + export const VirtualToolEmbeddingRanking = defineAndMigrateExpSetting('chat.advanced.virtualTools.embeddingRanking', 'chat.virtualTools.embeddingRanking', false); + export const MultiReplaceStringGrok = defineAndMigrateExpSetting('chat.advanced.multiReplaceStringGrok.enabled', 'chat.multiReplaceStringGrok.enabled', false); + } + + /** + * Internal settings those only team members can configure + * Features should only be in this list temporarily, moving on to experimental to be accessible to early adopters. + */ + export namespace Internal { + /** Allows forcing a particular context window size. + * This setting doesn't validate values so large windows may not be supported by the model. + * Note: this should not be used while self-hosting because it might lead to + * a fundamental different experience compared to our end-users. + */ + export const DebugOverrideChatMaxTokenNum = defineSetting('chat.advanced.debug.overrideChatMaxTokenNum', 0, INTERNAL_RESTRICTED); + /** Allow reporting issue when clicking on the Unhelpful button + * Requires a window reload to take effect + */ + export const DebugReportFeedback = defineSetting('chat.advanced.debug.reportFeedback', { defaultValue: false, teamDefaultValue: true }, INTERNAL_RESTRICTED); + export const DebugCollectFetcherTelemetry = defineExpSetting('chat.advanced.debug.collectFetcherTelemetry', true, INTERNAL_RESTRICTED); + export const DebugExpUseNodeFetchFetcher = defineExpSetting('chat.advanced.debug.useNodeFetchFetcher', undefined, INTERNAL_RESTRICTED); + export const DebugExpUseNodeFetcher = defineExpSetting('chat.advanced.debug.useNodeFetcher', undefined, INTERNAL_RESTRICTED); + export const DebugExpUseElectronFetcher = defineExpSetting('chat.advanced.debug.useElectronFetcher', undefined, INTERNAL_RESTRICTED); export const InlineEditsIgnoreCompletionsDisablement = defineValidatedSetting('chat.advanced.inlineEdits.ignoreCompletionsDisablement', vBoolean(), false, INTERNAL_RESTRICTED); export const InlineEditsAsyncCompletions = defineExpSetting('chat.advanced.inlineEdits.asyncCompletions', true, INTERNAL_RESTRICTED); export const InlineEditsDebounceUseCoreRequestTime = defineExpSetting('chat.advanced.inlineEdits.debounceUseCoreRequestTime', false, INTERNAL_RESTRICTED); @@ -708,9 +754,6 @@ export namespace ConfigKey { export const InlineEditsHideInternalInterface = defineValidatedSetting('chat.advanced.inlineEdits.hideInternalInterface', vBoolean(), false, INTERNAL_RESTRICTED); export const InlineEditsLogCancelledRequests = defineValidatedSetting('chat.advanced.inlineEdits.logCancelledRequests', vBoolean(), false, INTERNAL_RESTRICTED); export const InlineEditsUnification = defineExpSetting('chat.advanced.inlineEdits.unification', false, INTERNAL_RESTRICTED); - export const InlineEditsTriggerOnEditorChangeAfterSeconds = defineAndMigrateExpSetting('chat.advanced.inlineEdits.triggerOnEditorChangeAfterSeconds', 'chat.inlineEdits.triggerOnEditorChangeAfterSeconds', { defaultValue: undefined, teamDefaultValue: 10 }); - export const InlineEditsNextCursorPredictionDisplayLine = defineAndMigrateExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.displayLine', 'chat.inlineEdits.nextCursorPrediction.displayLine', true); - export const InlineEditsNextCursorPredictionCurrentFileMaxTokens = defineAndMigrateExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.currentFileMaxTokens', 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens', xtabPromptOptions.DEFAULT_OPTIONS.currentFile.maxTokens); export const InlineEditsNextCursorPredictionEnabled = defineExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.enabled', { defaultValue: undefined, teamDefaultValue: NextCursorLinePrediction.LabelOnlyWithEdit }, INTERNAL_RESTRICTED); export const InlineEditsNextCursorPredictionModelName = defineExpSetting('chat.advanced.inlineEdits.nextCursorPrediction.modelName', { defaultValue: undefined, teamDefaultValue: "xtab-cursor-jump-v2" }, INTERNAL_RESTRICTED); export const InlineEditsNextCursorPredictionUrl = defineValidatedSetting('chat.advanced.inlineEdits.nextCursorPrediction.url', vString(), undefined, INTERNAL_RESTRICTED); @@ -749,46 +792,14 @@ export namespace ConfigKey { export const InlineEditsXtabOnlyMergeConflictLines = defineExpSetting('chat.advanced.inlineEdits.xtabProvider.onlyMergeConflictLines', false, INTERNAL_RESTRICTED); export const InlineEditsUndoInsertionFiltering = defineExpSetting<'v1' | 'v2' | undefined>('chat.advanced.inlineEdits.undoInsertionFiltering', 'v1', INTERNAL_RESTRICTED); export const InlineEditsDiagnosticsExplorationEnabled = defineSetting('chat.advanced.inlineEdits.inlineEditsDiagnosticsExplorationEnabled', false, INTERNAL_RESTRICTED); - export const EditSourceTrackingShowDecorations = defineAndMigrateSetting('chat.advanced.editSourceTracking.showDecorations', 'chat.editSourceTracking.showDecorations', false); - export const EditSourceTrackingShowStatusBar = defineAndMigrateSetting('chat.advanced.editSourceTracking.showStatusBar', 'chat.editSourceTracking.showStatusBar', false); - export const WorkspaceRecordingEnabled = defineAndMigrateSetting('chat.advanced.localWorkspaceRecording.enabled', 'chat.localWorkspaceRecording.enabled', false); - export const EditRecordingEnabled = defineAndMigrateSetting('chat.advanced.editRecording.enabled', 'chat.editRecording.enabled', false); export const InternalWelcomeHintEnabled = defineSetting('chat.advanced.welcomePageHint.enabled', { defaultValue: false, internalDefaultValue: true, teamDefaultValue: true }, INTERNAL_RESTRICTED); - /** Configure temporal context max age */ - export const TemporalContextMaxAge = defineAndMigrateExpSetting('chat.advanced.temporalContext.maxAge', 'chat.temporalContext.maxAge', 100); - export const TemporalContextPreferSameLang = defineAndMigrateExpSetting('chat.advanced.temporalContext.preferSameLang', 'chat.temporalContext.preferSameLang', false); - export const CodeSearchAgentEnabled = defineAndMigrateSetting('chat.advanced.codesearch.agent.enabled', 'chat.codesearch.agent.enabled', true); - export const AgentTemperature = defineAndMigrateSetting('chat.advanced.agent.temperature', 'chat.agent.temperature', undefined); - export const InlineChatUseCodeMapper = defineSetting('chat.advanced.inlineChat.useCodeMapper', false, INTERNAL_RESTRICTED); export const InstantApplyModelName = defineExpSetting('chat.advanced.instantApply.modelName', 'gpt-4o-instant-apply-full-ft-v66', INTERNAL_RESTRICTED); - export const InstantApplyShortModelName = defineAndMigrateExpSetting('chat.advanced.instantApply.shortContextModelName', 'chat.instantApply.shortContextModelName', CHAT_MODEL.SHORT_INSTANT_APPLY); - export const InstantApplyShortContextLimit = defineAndMigrateExpSetting('chat.advanced.instantApply.shortContextLimit', 'chat.instantApply.shortContextLimit', 8000); - - export const EnableUserPreferences = defineAndMigrateSetting('chat.advanced.enableUserPreferences', 'chat.enableUserPreferences', false); - - export const SummarizeAgentConversationHistoryThreshold = defineAndMigrateSetting('chat.advanced.summarizeAgentConversationHistoryThreshold', 'chat.summarizeAgentConversationHistoryThreshold', undefined); - export const AgentHistorySummarizationMode = defineAndMigrateSetting('chat.advanced.agentHistorySummarizationMode', 'chat.agentHistorySummarizationMode', undefined); - export const AgentHistorySummarizationWithPromptCache = defineAndMigrateExpSetting('chat.advanced.agentHistorySummarizationWithPromptCache', 'chat.agentHistorySummarizationWithPromptCache', false); - export const AgentHistorySummarizationForceGpt41 = defineAndMigrateExpSetting('chat.advanced.agentHistorySummarizationForceGpt41', 'chat.agentHistorySummarizationForceGpt41', false); - export const UseResponsesApiTruncation = defineSetting('chat.advanced.useResponsesApiTruncation', false); + export const VerifyTextDocumentChanges = defineExpSetting('chat.advanced.inlineEdits.verifyTextDocumentChanges', false, INTERNAL_RESTRICTED); + // TODO: @sandy081 - These should be moved away from this namespace export const EnableReadFileV2 = defineExpSetting('chat.advanced.enableReadFileV2', isPreRelease); export const AskAgent = defineExpSetting('chat.advanced.enableAskAgent', { defaultValue: false, teamDefaultValue: true, internalDefaultValue: true }); - export const VerifyTextDocumentChanges = defineExpSetting('chat.advanced.inlineEdits.verifyTextDocumentChanges', false, INTERNAL_RESTRICTED); - export const OmitBaseAgentInstructions = defineAndMigrateSetting('chat.advanced.omitBaseAgentInstructions', 'chat.omitBaseAgentInstructions', false); - - export const PromptFileContext = defineExpSetting('chat.advanced.promptFileContextProvider.enabled', true); - export const DefaultToolsGrouped = defineAndMigrateExpSetting('chat.advanced.tools.defaultToolsGrouped', 'chat.tools.defaultToolsGrouped', false); - export const VirtualToolEmbeddingRanking = defineAndMigrateExpSetting('chat.advanced.virtualTools.embeddingRanking', 'chat.virtualTools.embeddingRanking', false); - export const MultiReplaceStringGrok = defineAndMigrateExpSetting('chat.advanced.multiReplaceStringGrok.enabled', 'chat.multiReplaceStringGrok.enabled', false); - - export const EnableClaudeCodeAgent = defineSetting('chat.advanced.claudeCode.enabled', false); - export const ClaudeCodeDebugEnabled = defineSetting('chat.advanced.claudeCode.debug', false); - export const CopilotCLIEnabled = defineSetting('chat.advanced.copilotCLI.enabled', true); - export const CLIIsolationEnabled = defineSetting('chat.advanced.cli.isolation.enabled', false); - export const CLIMCPServerEnabled = defineSetting('chat.advanced.cli.mcp.enabled', false); - export const Gpt5AlternativePatch = defineExpSetting('chat.advanced.gpt5AlternativePatch', false); } export const Enable = defineSetting<{ [key: string]: boolean }>('enable', { diff --git a/src/platform/configuration/test/common/configurationService.spec.ts b/src/platform/configuration/test/common/configurationService.spec.ts index e69b400081..561fe77c09 100644 --- a/src/platform/configuration/test/common/configurationService.spec.ts +++ b/src/platform/configuration/test/common/configurationService.spec.ts @@ -55,224 +55,224 @@ suite('AbstractConfigurationService', () => { suite('Internal Settings - Validation', () => { test('ProjectLabelsChat is correctly configured', () => { - const setting = ConfigKey.Internal.ProjectLabelsChat; + const setting = ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsChat; assert.strictEqual(setting.id, 'chat.projectLabels.chat'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('ProjectLabelsInline is correctly configured', () => { - const setting = ConfigKey.Internal.ProjectLabelsInline; + const setting = ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsInline; assert.strictEqual(setting.id, 'chat.projectLabels.inline'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('ProjectLabelsExpanded is correctly configured', () => { - const setting = ConfigKey.Internal.ProjectLabelsExpanded; + const setting = ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsExpanded; assert.strictEqual(setting.id, 'chat.projectLabels.expanded'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('WorkspaceMaxLocalIndexSize is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspaceMaxLocalIndexSize; + const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceMaxLocalIndexSize; assert.strictEqual(setting.id, 'chat.workspace.maxLocalIndexSize'); assert.strictEqual(setting.defaultValue, 100_000); assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableFullWorkspace is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspaceEnableFullWorkspace; + const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableFullWorkspace; assert.strictEqual(setting.id, 'chat.workspace.enableFullWorkspace'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableCodeSearch is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspaceEnableCodeSearch; + const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableCodeSearch; assert.strictEqual(setting.id, 'chat.workspace.enableCodeSearch'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableEmbeddingsSearch is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspaceEnableEmbeddingsSearch; + const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableEmbeddingsSearch; assert.strictEqual(setting.id, 'chat.workspace.enableEmbeddingsSearch'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, true); }); test('WorkspacePreferredEmbeddingsModel is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspacePreferredEmbeddingsModel; + const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspacePreferredEmbeddingsModel; assert.strictEqual(setting.id, 'chat.workspace.preferredEmbeddingsModel'); assert.strictEqual(setting.defaultValue, ''); assert.strictEqual(setting.isPublic, true); }); test('WorkspacePrototypeAdoCodeSearchEndpointOverride is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspacePrototypeAdoCodeSearchEndpointOverride; + const setting = ConfigKey.AdvancedExperimental.WorkspacePrototypeAdoCodeSearchEndpointOverride; assert.strictEqual(setting.id, 'chat.workspace.prototypeAdoCodeSearchEndpointOverride'); assert.strictEqual(setting.defaultValue, ''); assert.strictEqual(setting.isPublic, true); }); test('FeedbackOnChange is correctly configured', () => { - const setting = ConfigKey.Internal.FeedbackOnChange; + const setting = ConfigKey.AdvancedExperimental.FeedbackOnChange; assert.strictEqual(setting.id, 'chat.feedback.onChange'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('ReviewIntent is correctly configured', () => { - const setting = ConfigKey.Internal.ReviewIntent; + const setting = ConfigKey.AdvancedExperimental.ReviewIntent; assert.strictEqual(setting.id, 'chat.review.intent'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('NotebookSummaryExperimentEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.NotebookSummaryExperimentEnabled; + const setting = ConfigKey.AdvancedExperimental.NotebookSummaryExperimentEnabled; assert.strictEqual(setting.id, 'chat.notebook.summaryExperimentEnabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('NotebookVariableFilteringEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.NotebookVariableFilteringEnabled; + const setting = ConfigKey.AdvancedExperimental.NotebookVariableFilteringEnabled; assert.strictEqual(setting.id, 'chat.notebook.variableFilteringEnabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('NotebookAlternativeDocumentFormat is correctly configured', () => { - const setting = ConfigKey.Internal.NotebookAlternativeDocumentFormat; + const setting = ConfigKey.AdvancedExperimentalExperiments.NotebookAlternativeDocumentFormat; assert.strictEqual(setting.id, 'chat.notebook.alternativeFormat'); assert.strictEqual(setting.defaultValue, AlternativeNotebookFormat.xml); assert.strictEqual(setting.isPublic, true); }); test('UseAlternativeNESNotebookFormat is correctly configured', () => { - const setting = ConfigKey.Internal.UseAlternativeNESNotebookFormat; + const setting = ConfigKey.AdvancedExperimentalExperiments.UseAlternativeNESNotebookFormat; assert.strictEqual(setting.id, 'chat.notebook.alternativeNESFormat.enabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('TerminalToDebuggerPatterns is correctly configured', () => { - const setting = ConfigKey.Internal.TerminalToDebuggerPatterns; + const setting = ConfigKey.AdvancedExperimental.TerminalToDebuggerPatterns; assert.strictEqual(setting.id, 'chat.debugTerminalCommandPatterns'); assert.deepStrictEqual(setting.defaultValue, []); assert.strictEqual(setting.isPublic, true); }); test('EditSourceTrackingShowDecorations is correctly configured', () => { - const setting = ConfigKey.Internal.EditSourceTrackingShowDecorations; + const setting = ConfigKey.AdvancedExperimental.EditSourceTrackingShowDecorations; assert.strictEqual(setting.id, 'chat.editSourceTracking.showDecorations'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('EditSourceTrackingShowStatusBar is correctly configured', () => { - const setting = ConfigKey.Internal.EditSourceTrackingShowStatusBar; + const setting = ConfigKey.AdvancedExperimental.EditSourceTrackingShowStatusBar; assert.strictEqual(setting.id, 'chat.editSourceTracking.showStatusBar'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('WorkspaceRecordingEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.WorkspaceRecordingEnabled; + const setting = ConfigKey.AdvancedExperimental.WorkspaceRecordingEnabled; assert.strictEqual(setting.id, 'chat.localWorkspaceRecording.enabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('EditRecordingEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.EditRecordingEnabled; + const setting = ConfigKey.AdvancedExperimental.EditRecordingEnabled; assert.strictEqual(setting.id, 'chat.editRecording.enabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('TemporalContextMaxAge is correctly configured', () => { - const setting = ConfigKey.Internal.TemporalContextMaxAge; + const setting = ConfigKey.AdvancedExperimentalExperiments.TemporalContextMaxAge; assert.strictEqual(setting.id, 'chat.temporalContext.maxAge'); assert.strictEqual(setting.defaultValue, 100); assert.strictEqual(setting.isPublic, true); }); test('TemporalContextPreferSameLang is correctly configured', () => { - const setting = ConfigKey.Internal.TemporalContextPreferSameLang; + const setting = ConfigKey.AdvancedExperimentalExperiments.TemporalContextPreferSameLang; assert.strictEqual(setting.id, 'chat.temporalContext.preferSameLang'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('CodeSearchAgentEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.CodeSearchAgentEnabled; + const setting = ConfigKey.AdvancedExperimental.CodeSearchAgentEnabled; assert.strictEqual(setting.id, 'chat.codesearch.agent.enabled'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, true); }); test('AgentTemperature is correctly configured', () => { - const setting = ConfigKey.Internal.AgentTemperature; + const setting = ConfigKey.AdvancedExperimental.AgentTemperature; assert.strictEqual(setting.id, 'chat.agent.temperature'); assert.strictEqual(setting.defaultValue, undefined); assert.strictEqual(setting.isPublic, true); }); test('InstantApplyShortModelName is correctly configured', () => { - const setting = ConfigKey.Internal.InstantApplyShortModelName; + const setting = ConfigKey.AdvancedExperimentalExperiments.InstantApplyShortModelName; assert.strictEqual(setting.id, 'chat.instantApply.shortContextModelName'); assert.strictEqual(setting.defaultValue, 'gpt-4o-instant-apply-full-ft-v66-short'); assert.strictEqual(setting.isPublic, true); }); test('InstantApplyShortContextLimit is correctly configured', () => { - const setting = ConfigKey.Internal.InstantApplyShortContextLimit; + const setting = ConfigKey.AdvancedExperimentalExperiments.InstantApplyShortContextLimit; assert.strictEqual(setting.id, 'chat.instantApply.shortContextLimit'); assert.strictEqual(setting.defaultValue, 8000); assert.strictEqual(setting.isPublic, true); }); test('EnableUserPreferences is correctly configured', () => { - const setting = ConfigKey.Internal.EnableUserPreferences; + const setting = ConfigKey.AdvancedExperimental.EnableUserPreferences; assert.strictEqual(setting.id, 'chat.enableUserPreferences'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('SummarizeAgentConversationHistoryThreshold is correctly configured', () => { - const setting = ConfigKey.Internal.SummarizeAgentConversationHistoryThreshold; + const setting = ConfigKey.AdvancedExperimental.SummarizeAgentConversationHistoryThreshold; assert.strictEqual(setting.id, 'chat.summarizeAgentConversationHistoryThreshold'); assert.strictEqual(setting.defaultValue, undefined); assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationMode is correctly configured', () => { - const setting = ConfigKey.Internal.AgentHistorySummarizationMode; + const setting = ConfigKey.AdvancedExperimental.AgentHistorySummarizationMode; assert.strictEqual(setting.id, 'chat.agentHistorySummarizationMode'); assert.strictEqual(setting.defaultValue, undefined); assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationWithPromptCache is correctly configured', () => { - const setting = ConfigKey.Internal.AgentHistorySummarizationWithPromptCache; + const setting = ConfigKey.AdvancedExperimentalExperiments.AgentHistorySummarizationWithPromptCache; assert.strictEqual(setting.id, 'chat.agentHistorySummarizationWithPromptCache'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationForceGpt41 is correctly configured', () => { - const setting = ConfigKey.Internal.AgentHistorySummarizationForceGpt41; + const setting = ConfigKey.AdvancedExperimentalExperiments.AgentHistorySummarizationForceGpt41; assert.strictEqual(setting.id, 'chat.agentHistorySummarizationForceGpt41'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('UseResponsesApiTruncation is correctly configured', () => { - const setting = ConfigKey.Internal.UseResponsesApiTruncation; + const setting = ConfigKey.AdvancedExperimental.UseResponsesApiTruncation; assert.strictEqual(setting.id, 'chat.advanced.useResponsesApiTruncation'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, false); @@ -280,14 +280,14 @@ suite('AbstractConfigurationService', () => { }); test('OmitBaseAgentInstructions is correctly configured', () => { - const setting = ConfigKey.Internal.OmitBaseAgentInstructions; + const setting = ConfigKey.AdvancedExperimental.OmitBaseAgentInstructions; assert.strictEqual(setting.id, 'chat.omitBaseAgentInstructions'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('PromptFileContext is correctly configured', () => { - const setting = ConfigKey.Internal.PromptFileContext; + const setting = ConfigKey.AdvancedExperimentalExperiments.PromptFileContext; assert.strictEqual(setting.id, 'chat.advanced.promptFileContextProvider.enabled'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, false); @@ -295,28 +295,28 @@ suite('AbstractConfigurationService', () => { }); test('DefaultToolsGrouped is correctly configured', () => { - const setting = ConfigKey.Internal.DefaultToolsGrouped; + const setting = ConfigKey.AdvancedExperimentalExperiments.DefaultToolsGrouped; assert.strictEqual(setting.id, 'chat.tools.defaultToolsGrouped'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('VirtualToolEmbeddingRanking is correctly configured', () => { - const setting = ConfigKey.Internal.VirtualToolEmbeddingRanking; + const setting = ConfigKey.AdvancedExperimentalExperiments.VirtualToolEmbeddingRanking; assert.strictEqual(setting.id, 'chat.virtualTools.embeddingRanking'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('MultiReplaceStringGrok is correctly configured', () => { - const setting = ConfigKey.Internal.MultiReplaceStringGrok; + const setting = ConfigKey.AdvancedExperimentalExperiments.MultiReplaceStringGrok; assert.strictEqual(setting.id, 'chat.multiReplaceStringGrok.enabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, true); }); test('EnableClaudeCodeAgent is correctly configured', () => { - const setting = ConfigKey.Internal.EnableClaudeCodeAgent; + const setting = ConfigKey.AdvancedExperimental.EnableClaudeCodeAgent; assert.strictEqual(setting.id, 'chat.advanced.claudeCode.enabled'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, false); @@ -324,7 +324,7 @@ suite('AbstractConfigurationService', () => { }); test('ClaudeCodeDebugEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.ClaudeCodeDebugEnabled; + const setting = ConfigKey.AdvancedExperimental.ClaudeCodeDebugEnabled; assert.strictEqual(setting.id, 'chat.advanced.claudeCode.debug'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, false); @@ -332,7 +332,7 @@ suite('AbstractConfigurationService', () => { }); test('CopilotCLIEnabled is correctly configured', () => { - const setting = ConfigKey.Internal.CopilotCLIEnabled; + const setting = ConfigKey.AdvancedExperimental.CopilotCLIEnabled; assert.strictEqual(setting.id, 'chat.advanced.copilotCLI.enabled'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, false); @@ -340,7 +340,7 @@ suite('AbstractConfigurationService', () => { }); test('Gpt5AlternativePatch is correctly configured', () => { - const setting = ConfigKey.Internal.Gpt5AlternativePatch; + const setting = ConfigKey.AdvancedExperimentalExperiments.Gpt5AlternativePatch; assert.strictEqual(setting.id, 'chat.advanced.gpt5AlternativePatch'); assert.strictEqual(setting.defaultValue, false); assert.strictEqual(setting.isPublic, false); @@ -348,7 +348,7 @@ suite('AbstractConfigurationService', () => { }); test('InlineEditsTriggerOnEditorChangeAfterSeconds is correctly configured', () => { - const setting = ConfigKey.Internal.InlineEditsTriggerOnEditorChangeAfterSeconds; + const setting = ConfigKey.AdvancedExperimentalExperiments.InlineEditsTriggerOnEditorChangeAfterSeconds; assert.strictEqual(setting.id, 'chat.inlineEdits.triggerOnEditorChangeAfterSeconds'); const defaultValue = setting.defaultValue as DefaultValueWithTeamValue; assert.strictEqual(defaultValue.defaultValue, undefined); @@ -357,14 +357,14 @@ suite('AbstractConfigurationService', () => { }); test('InlineEditsNextCursorPredictionDisplayLine is correctly configured', () => { - const setting = ConfigKey.Internal.InlineEditsNextCursorPredictionDisplayLine; + const setting = ConfigKey.AdvancedExperimentalExperiments.InlineEditsNextCursorPredictionDisplayLine; assert.strictEqual(setting.id, 'chat.inlineEdits.nextCursorPrediction.displayLine'); assert.strictEqual(setting.defaultValue, true); assert.strictEqual(setting.isPublic, true); }); test('InlineEditsNextCursorPredictionCurrentFileMaxTokens is correctly configured', () => { - const setting = ConfigKey.Internal.InlineEditsNextCursorPredictionCurrentFileMaxTokens; + const setting = ConfigKey.AdvancedExperimentalExperiments.InlineEditsNextCursorPredictionCurrentFileMaxTokens; assert.strictEqual(setting.id, 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens'); assert.strictEqual(setting.defaultValue, 2000); assert.strictEqual(setting.isPublic, true); diff --git a/src/platform/configuration/vscode/configurationServiceImpl.ts b/src/platform/configuration/vscode/configurationServiceImpl.ts index 0a082da5e1..acf92b6506 100644 --- a/src/platform/configuration/vscode/configurationServiceImpl.ts +++ b/src/platform/configuration/vscode/configurationServiceImpl.ts @@ -5,10 +5,11 @@ import type { WorkspaceConfiguration } from 'vscode'; import * as vscode from 'vscode'; +import { distinct } from '../../../util/vs/base/common/arrays'; import { ICopilotTokenStore } from '../../authentication/common/copilotTokenStore'; import { packageJson } from '../../env/common/packagejson'; import { IExperimentationService } from '../../telemetry/common/nullExperimentationService'; -import { AbstractConfigurationService, BaseConfig, Config, ConfigValueValidators, CopilotConfigPrefix, ExperimentBasedConfig, ExperimentBasedConfigType, InspectConfigResult } from '../common/configurationService'; +import { AbstractConfigurationService, BaseConfig, Config, ConfigValueValidators, CopilotConfigPrefix, ExperimentBasedConfig, ExperimentBasedConfigType, globalConfigRegistry, InspectConfigResult } from '../common/configurationService'; // Helper to avoid JSON.stringify quoting strings function stringOrStringify(value: any) { @@ -30,7 +31,18 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { if (changeEvent.affectsConfiguration(CopilotConfigPrefix)) { this.config = vscode.workspace.getConfiguration(CopilotConfigPrefix); } - this._onDidChangeConfiguration.fire(changeEvent); + this._onDidChangeConfiguration.fire({ + affectsConfiguration: (section: string, scope?: vscode.ConfigurationScope) => { + if (changeEvent.affectsConfiguration(section, scope)) { + return true; + } + const oldId = globalConfigRegistry.configs.get(section)?.fullyQualifiedOldId; + if (oldId && changeEvent.affectsConfiguration(oldId, scope)) { + return true; + } + return false; + } + }); }); } @@ -68,10 +80,10 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { // or internal users, so the (public) default value used by vscode is not the same. // We need to really check if the user or workspace configured the setting if (this.isConfigured(key, scope)) { - configuredValue = config.get(key.id); + configuredValue = config.get(key.id) ?? (key.oldId ? config.get(key.oldId) : undefined); } } else { - configuredValue = config.get(key.id); + configuredValue = config.get(key.id) ?? (key.oldId ? config.get(key.oldId) : undefined); } } @@ -98,7 +110,24 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { } const config = scope === undefined ? this.config : vscode.workspace.getConfiguration(CopilotConfigPrefix, scope); - return config.inspect(key.id); + const inspectResult = config.inspect(key.id); + if (!key.oldId) { + return inspectResult; + } + + const oldInspectResult = config.inspect(key.oldId); + const languageIds = distinct([...inspectResult?.languageIds ?? [], ...oldInspectResult?.languageIds ?? []]); + return { + defaultValue: inspectResult?.defaultValue ?? oldInspectResult?.defaultValue, + globalValue: inspectResult?.globalValue ?? oldInspectResult?.globalValue, + workspaceValue: inspectResult?.workspaceValue ?? oldInspectResult?.workspaceValue, + workspaceFolderValue: inspectResult?.workspaceFolderValue ?? oldInspectResult?.workspaceFolderValue, + defaultLanguageValue: inspectResult?.defaultLanguageValue ?? oldInspectResult?.defaultLanguageValue, + globalLanguageValue: inspectResult?.globalLanguageValue ?? oldInspectResult?.globalLanguageValue, + workspaceLanguageValue: inspectResult?.workspaceLanguageValue ?? oldInspectResult?.workspaceLanguageValue, + workspaceFolderLanguageValue: inspectResult?.workspaceFolderLanguageValue ?? oldInspectResult?.workspaceFolderLanguageValue, + languageIds: languageIds.length ? languageIds : undefined, + }; } override getNonExtensionConfig(configKey: string): T | undefined { @@ -190,6 +219,13 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { return expValue2; } + if (key.fullyQualifiedOldId) { + const oldExpValue = experimentationService.getTreatmentVariable>(`config.${key.fullyQualifiedOldId}`); + if (oldExpValue !== undefined) { + return oldExpValue; + } + } + return this.getDefaultValue(key); } @@ -206,7 +242,7 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { return undefined; } - return config.get(key.id); + return config.get(key.id) ?? (key.oldId ? config.get(key.oldId) : undefined); } // Dumps config settings defined in the extension json diff --git a/src/platform/endpoint/node/proxyInstantApplyShortEndpoint.ts b/src/platform/endpoint/node/proxyInstantApplyShortEndpoint.ts index e74cdc0d2b..99f09f5f3a 100644 --- a/src/platform/endpoint/node/proxyInstantApplyShortEndpoint.ts +++ b/src/platform/endpoint/node/proxyInstantApplyShortEndpoint.ts @@ -34,7 +34,7 @@ export class ProxyInstantApplyShortEndpoint extends ChatEndpoint { @IExperimentationService experimentationService: IExperimentationService, @ILogService logService: ILogService, ) { - const model = configurationService.getExperimentBasedConfig(ConfigKey.Internal.InstantApplyShortModelName, experimentationService) ?? CHAT_MODEL.SHORT_INSTANT_APPLY; + const model = configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.InstantApplyShortModelName, experimentationService) ?? CHAT_MODEL.SHORT_INSTANT_APPLY; const modelInfo: IChatModelInformation = { id: model, name: model, diff --git a/src/platform/endpoint/node/responsesApi.ts b/src/platform/endpoint/node/responsesApi.ts index e3bde2b837..1b968665ba 100644 --- a/src/platform/endpoint/node/responsesApi.ts +++ b/src/platform/endpoint/node/responsesApi.ts @@ -53,7 +53,7 @@ export function createResponsesRequestBody(accessor: ServicesAccessor, options: text: verbosity ? { verbosity } : undefined, }; - body.truncation = configService.getConfig(ConfigKey.Internal.UseResponsesApiTruncation) ? + body.truncation = configService.getConfig(ConfigKey.AdvancedExperimental.UseResponsesApiTruncation) ? 'auto' : 'disabled'; const effortConfig = configService.getExperimentBasedConfig(ConfigKey.ResponsesApiReasoningEffort, expService); diff --git a/src/platform/multiFileEdit/common/editLogService.ts b/src/platform/multiFileEdit/common/editLogService.ts index 359b632db2..e55c2545d0 100644 --- a/src/platform/multiFileEdit/common/editLogService.ts +++ b/src/platform/multiFileEdit/common/editLogService.ts @@ -77,7 +77,7 @@ export class EditLogService implements IEditLogService { ) { } private _isEnabled() { - return this._configurationService.getConfig(ConfigKey.Internal.EditRecordingEnabled); + return this._configurationService.getConfig(ConfigKey.AdvancedExperimental.EditRecordingEnabled); } logEditChatRequest(turnId: string, prompt: ReadonlyArray, response: string): void { diff --git a/src/platform/notebook/common/alternativeContent.ts b/src/platform/notebook/common/alternativeContent.ts index 5bd4680cab..fcaa8e5b2a 100644 --- a/src/platform/notebook/common/alternativeContent.ts +++ b/src/platform/notebook/common/alternativeContent.ts @@ -67,7 +67,7 @@ export class AlternativeNotebookContentService implements IAlternativeNotebookCo return 'json'; } - return this.configurationService.getExperimentBasedConfig(ConfigKey.Internal.NotebookAlternativeDocumentFormat, this.experimentationService); + return this.configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.NotebookAlternativeDocumentFormat, this.experimentationService); } create(format: AlternativeContentFormat): BaseAlternativeNotebookContentProvider { diff --git a/src/platform/notebook/vscode/notebookServiceImpl.ts b/src/platform/notebook/vscode/notebookServiceImpl.ts index 21978964be..324997d940 100644 --- a/src/platform/notebook/vscode/notebookServiceImpl.ts +++ b/src/platform/notebook/vscode/notebookServiceImpl.ts @@ -46,7 +46,7 @@ export class NotebookService implements INotebookService { @ILogService private readonly _logger: ILogService, ) { this._isVariableFilteringEnabled = this._experimentationService.getTreatmentVariable('copilotchat.notebookVariableFiltering') - || this._configurationService.getConfig(ConfigKey.Internal.NotebookVariableFilteringEnabled); + || this._configurationService.getConfig(ConfigKey.AdvancedExperimental.NotebookVariableFilteringEnabled); this._registerExecutionListener(); } diff --git a/src/platform/remoteCodeSearch/common/adoCodeSearchService.ts b/src/platform/remoteCodeSearch/common/adoCodeSearchService.ts index 991553d3fe..182dc59910 100644 --- a/src/platform/remoteCodeSearch/common/adoCodeSearchService.ts +++ b/src/platform/remoteCodeSearch/common/adoCodeSearchService.ts @@ -264,7 +264,7 @@ export class AdoCodeSearchService extends Disposable implements IAdoCodeSearchSe throw new Error('No valid auth token'); } - let endpoint = this._configurationService.getConfig(ConfigKey.Internal.WorkspacePrototypeAdoCodeSearchEndpointOverride); + let endpoint = this._configurationService.getConfig(ConfigKey.AdvancedExperimental.WorkspacePrototypeAdoCodeSearchEndpointOverride); if (!endpoint) { endpoint = this.getAdoAlmSearchUrl(repo.adoRepoId); } diff --git a/src/platform/review/vscode/reviewServiceImpl.ts b/src/platform/review/vscode/reviewServiceImpl.ts index b169d97f34..550e590ec3 100644 --- a/src/platform/review/vscode/reviewServiceImpl.ts +++ b/src/platform/review/vscode/reviewServiceImpl.ts @@ -44,7 +44,7 @@ export class ReviewServiceImpl implements IReviewService { vscode.commands.executeCommand('setContext', ConfigKey.CodeFeedback.fullyQualifiedId, this.isCodeFeedbackEnabled()); } if (e.affectsConfiguration('github.copilot.advanced') || e.affectsConfiguration('github.copilot.advanced.review.intent')) { - vscode.commands.executeCommand('setContext', ConfigKey.Internal.ReviewIntent.fullyQualifiedId, this.isIntentEnabled()); + vscode.commands.executeCommand('setContext', ConfigKey.AdvancedExperimental.ReviewIntent.fullyQualifiedId, this.isIntentEnabled()); } })); this._disposables.add(this._authenticationService.onDidAuthenticationChange(() => { @@ -97,7 +97,7 @@ export class ReviewServiceImpl implements IReviewService { updateContextValues(): void { vscode.commands.executeCommand('setContext', ConfigKey.CodeFeedback.fullyQualifiedId, this.isCodeFeedbackEnabled()); vscode.commands.executeCommand('setContext', reviewDiffContextKey, this.isReviewDiffEnabled()); - vscode.commands.executeCommand('setContext', ConfigKey.Internal.ReviewIntent.fullyQualifiedId, this.isIntentEnabled()); + vscode.commands.executeCommand('setContext', ConfigKey.AdvancedExperimental.ReviewIntent.fullyQualifiedId, this.isIntentEnabled()); } isCodeFeedbackEnabled() { @@ -110,7 +110,7 @@ export class ReviewServiceImpl implements IReviewService { } isIntentEnabled(): boolean { - return this._configurationService.getConfig(ConfigKey.Internal.ReviewIntent); + return this._configurationService.getConfig(ConfigKey.AdvancedExperimental.ReviewIntent); } getDiagnosticCollection(): ReviewDiagnosticCollection { diff --git a/src/platform/test/node/simulationWorkspaceServices.ts b/src/platform/test/node/simulationWorkspaceServices.ts index be423964d2..d04e460483 100644 --- a/src/platform/test/node/simulationWorkspaceServices.ts +++ b/src/platform/test/node/simulationWorkspaceServices.ts @@ -274,10 +274,10 @@ export class SimulationReviewService implements IReviewService { } isIntentEnabled(): boolean { - if (ConfigValueValidators.isDefaultValueWithTeamValue(ConfigKey.Internal.ReviewIntent.defaultValue)) { - return ConfigKey.Internal.ReviewIntent.defaultValue.defaultValue; + if (ConfigValueValidators.isDefaultValueWithTeamValue(ConfigKey.AdvancedExperimental.ReviewIntent.defaultValue)) { + return ConfigKey.AdvancedExperimental.ReviewIntent.defaultValue.defaultValue; } - return ConfigKey.Internal.ReviewIntent.defaultValue; + return ConfigKey.AdvancedExperimental.ReviewIntent.defaultValue; } getDiagnosticCollection(): ReviewDiagnosticCollection { diff --git a/src/platform/workspaceChunkSearch/common/githubAvailableEmbeddingTypes.ts b/src/platform/workspaceChunkSearch/common/githubAvailableEmbeddingTypes.ts index d73cf1f9bc..550ef36ab1 100644 --- a/src/platform/workspaceChunkSearch/common/githubAvailableEmbeddingTypes.ts +++ b/src/platform/workspaceChunkSearch/common/githubAvailableEmbeddingTypes.ts @@ -218,7 +218,7 @@ export class GithubAvailableEmbeddingTypesService implements IGithubAvailableEmb const all = result.val; this._logService.info(`GithubAvailableEmbeddingTypesManager: Got embeddings. Primary: ${all.primary.join(',')}. Deprecated: ${all.deprecated.join(',')}`); - const preference = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.WorkspacePreferredEmbeddingsModel, this._experimentationService); + const preference = this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.WorkspacePreferredEmbeddingsModel, this._experimentationService); if (preference) { const preferred = [...all.primary, ...all.deprecated].find(type => type.id === preference); if (preferred) { diff --git a/src/platform/workspaceChunkSearch/node/codeSearchChunkSearch.ts b/src/platform/workspaceChunkSearch/node/codeSearchChunkSearch.ts index 1b4b7a7e69..235e23e02a 100644 --- a/src/platform/workspaceChunkSearch/node/codeSearchChunkSearch.ts +++ b/src/platform/workspaceChunkSearch/node/codeSearchChunkSearch.ts @@ -317,7 +317,7 @@ export class CodeSearchChunkSearch extends Disposable implements IWorkspaceChunk } private isCodeSearchEnabled() { - return this._configService.getExperimentBasedConfig(ConfigKey.Internal.WorkspaceEnableCodeSearch, this._experimentationService); + return this._configService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableCodeSearch, this._experimentationService); } getRemoteIndexState(): CodeSearchRemoteIndexState { diff --git a/src/platform/workspaceChunkSearch/node/embeddingsChunkSearch.ts b/src/platform/workspaceChunkSearch/node/embeddingsChunkSearch.ts index ff6c4e4a0a..2c10543ca6 100644 --- a/src/platform/workspaceChunkSearch/node/embeddingsChunkSearch.ts +++ b/src/platform/workspaceChunkSearch/node/embeddingsChunkSearch.ts @@ -197,7 +197,7 @@ export class EmbeddingsChunkSearch extends Disposable implements IWorkspaceChunk } private isEmbeddingSearchEnabled() { - return this._configService.getExperimentBasedConfig(ConfigKey.Internal.WorkspaceEnableEmbeddingsSearch, this._experimentationService); + return this._configService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableEmbeddingsSearch, this._experimentationService); } @LogExecTime(self => self._logService, 'EmbeddingsChunkSearch::searchSubsetOfFiles') diff --git a/src/platform/workspaceChunkSearch/node/fullWorkspaceChunkSearch.ts b/src/platform/workspaceChunkSearch/node/fullWorkspaceChunkSearch.ts index 349381a5a5..74126f3cae 100644 --- a/src/platform/workspaceChunkSearch/node/fullWorkspaceChunkSearch.ts +++ b/src/platform/workspaceChunkSearch/node/fullWorkspaceChunkSearch.ts @@ -188,6 +188,6 @@ export class FullWorkspaceChunkSearch extends Disposable implements IWorkspaceCh } private isEnabled(): boolean { - return this._configService.getExperimentBasedConfig(ConfigKey.Internal.WorkspaceEnableFullWorkspace, this._experimentationService); + return this._configService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableFullWorkspace, this._experimentationService); } } diff --git a/src/platform/workspaceChunkSearch/node/workspaceFileIndex.ts b/src/platform/workspaceChunkSearch/node/workspaceFileIndex.ts index 80cb7c2497..3ae231efff 100644 --- a/src/platform/workspaceChunkSearch/node/workspaceFileIndex.ts +++ b/src/platform/workspaceChunkSearch/node/workspaceFileIndex.ts @@ -707,7 +707,7 @@ export class WorkspaceFileIndex extends Disposable implements IWorkspaceFileInde } private getMaxFilesToIndex(): number { - return this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.WorkspaceMaxLocalIndexSize, this._expService); + return this._configurationService.getExperimentBasedConfig(ConfigKey.AdvancedExperimentalExperiments.WorkspaceMaxLocalIndexSize, this._expService); } private async getWorkspaceFilesToIndex(maxResults: number, token: CancellationToken): Promise> { From e9f1f9e907d34ae7e7e6e365e76673ecb7754456 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 11 Nov 2025 16:36:03 +0100 Subject: [PATCH 3/7] make experiment change event aware of old id --- .../configuration/vscode/configurationServiceImpl.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platform/configuration/vscode/configurationServiceImpl.ts b/src/platform/configuration/vscode/configurationServiceImpl.ts index acf92b6506..474d7d1c20 100644 --- a/src/platform/configuration/vscode/configurationServiceImpl.ts +++ b/src/platform/configuration/vscode/configurationServiceImpl.ts @@ -283,8 +283,14 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { // Fire simulated event which checks if a configuration is affected in the treatments this._onDidChangeConfiguration.fire({ affectsConfiguration: (section: string, _scope?: vscode.ConfigurationScope) => { - const result = treatments.some(t => t.startsWith(`config.${section}`)); - return result; + if (treatments.some(t => t.startsWith(`config.${section}`))) { + return true; + } + const oldId = globalConfigRegistry.configs.get(section)?.fullyQualifiedOldId; + if (oldId && treatments.some(t => t.startsWith(`config.${oldId}`))) { + return true; + } + return false; } }); } From 8fee182320ff2dcf87fabd0fec77955b4d7b75a4 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 14 Nov 2025 15:04:31 +0100 Subject: [PATCH 4/7] fix tests --- .../test/node/configurations.spec.ts | 84 ++++++++++++------- .../common/configurationService.ts | 4 +- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/src/extension/test/node/configurations.spec.ts b/src/extension/test/node/configurations.spec.ts index 9e09a7bb23..1845b9d770 100644 --- a/src/extension/test/node/configurations.spec.ts +++ b/src/extension/test/node/configurations.spec.ts @@ -9,58 +9,80 @@ import { Config, ConfigKey } from '../../../platform/configuration/common/config import { packageJson } from '../../../platform/env/common/packagejson'; describe('Configurations', () => { - it('package.json configuration contains stable, experimental, and preview sections', () => { + it('package.json configuration contains stable, experimental, preview, and advanced sections', () => { const configurationContributions = packageJson.contributes.configuration; - // Should have 3 sections - expect(configurationContributions, 'package.json should have exactly 3 sections').toHaveLength(3); + // Should have 4 sections + expect(configurationContributions, 'package.json should have exactly 4 sections').toHaveLength(4); // Should have a stable section const stableSection = configurationContributions.find(section => section.id === 'stable'); const preview = configurationContributions.find(section => section.id === 'preview'); const experimental = configurationContributions.find(section => section.id === 'experimental'); + const advanced = configurationContributions.find(section => section.id === 'advanced'); expect(stableSection, 'stable configuration section is missing').toBeDefined(); expect(preview, 'preview configuration section is missing').toBeDefined(); expect(experimental, 'experimental configuration section is missing').toBeDefined(); + expect(advanced, 'advanced configuration section is missing').toBeDefined(); }); it('package.json configuration tags are correct for each section', () => { const configurationContributions = packageJson.contributes.configuration; - // Should have a stable section const stableSection = configurationContributions.find(section => section.id === 'stable')!; - const preview = configurationContributions.find(section => section.id === 'preview')!; - const experimental = configurationContributions.find(section => section.id === 'experimental')!; - - for (const section of [stableSection, preview, experimental]) { - const sectionSettings = Object.keys(section?.properties); - - for (const settingId of sectionSettings) { - const setting = section.properties[settingId]; - if (section.id === 'stable') { - expect(setting.tags ?? [], settingId).not.toContain('preview'); - expect(setting.tags ?? [], settingId).not.toContain('experimental'); - } else { - expect(setting.tags ?? [], settingId).toContain(section.id); - } - } + for (const settingId of Object.keys(stableSection?.properties)) { + const setting = stableSection.properties[settingId]; + expect(setting.tags ?? [], settingId).not.toContain('preview'); + expect(setting.tags ?? [], settingId).not.toContain('experimental'); + expect(setting.tags ?? [], settingId).not.toContain('advanced'); + } + + const previewSection = configurationContributions.find(section => section.id === 'preview')!; + for (const settingId of Object.keys(previewSection?.properties)) { + const setting = previewSection.properties[settingId]; + expect(setting.tags ?? [], settingId).toContain('preview'); + expect(setting.tags ?? [], settingId).not.toContain('experimental'); + expect(setting.tags ?? [], settingId).not.toContain('advanced'); + } + + const experimentalSection = configurationContributions.find(section => section.id === 'experimental')!; + for (const settingId of Object.keys(experimentalSection?.properties)) { + const setting = experimentalSection.properties[settingId]; + expect(setting.tags ?? [], settingId).toContain('experimental'); + expect(setting.tags ?? [], settingId).not.toContain('preview'); + expect(setting.tags ?? [], settingId).not.toContain('advanced'); + } + + const advancedSection = configurationContributions.find(section => section.id === 'advanced')!; + for (const settingId of Object.keys(advancedSection?.properties)) { + const setting = advancedSection.properties[settingId]; + expect(setting.tags ?? [], settingId).toContain('advanced'); + expect(setting.tags ?? [], settingId).not.toContain('preview'); } }); it('settings in code should match package.json', () => { + const configurationsInPackageJson = packageJson.contributes.configuration.flatMap(section => Object.keys(section.properties)); + const advancedConfigurationsInPackageJson = packageJson.contributes.configuration.filter(section => section.id === 'advanced').flatMap(section => Object.keys(section.properties)); + const otherConfigurationsInPackageJson = packageJson.contributes.configuration.filter(section => section.id !== 'advanced').flatMap(section => Object.keys(section.properties)); // Get keys from code - const publicConfigs = Object.values(ConfigKey).filter(key => key !== ConfigKey.Internal && key !== ConfigKey.Shared) as Config[]; const internalKeys = Object.values(ConfigKey.Internal).map(setting => setting.fullyQualifiedId); const sharedKeys = Object.values(ConfigKey.Shared).map(setting => setting.fullyQualifiedId); - const publicKeys = publicConfigs.map(setting => setting.fullyQualifiedId); - - // Validate Internal and Shared settings are not in package.json - [...internalKeys, ...sharedKeys].forEach(key => { - expect(configurationsInPackageJson, 'Internal settings and those shared with the completions extension should not be defined in the package.json').not.toContain(key); + const advancedPublicKeys = [ + ...Object.values(ConfigKey.AdvancedExperimental).map(setting => setting.fullyQualifiedId), + ...Object.values(ConfigKey.AdvancedExperimentalExperiments).map(setting => setting.fullyQualifiedId) + ]; + const otherPublicKeys = (Object.values(ConfigKey).filter(key => key !== ConfigKey.Internal && key !== ConfigKey.Shared && key !== ConfigKey.AdvancedExperimental && key !== ConfigKey.AdvancedExperimentalExperiments) as Config[]).map(setting => setting.fullyQualifiedId); + const registered = [...otherPublicKeys, ...advancedPublicKeys]; + const unregistered = [...internalKeys, ...sharedKeys]; + + // Validate unregistered settings are not in package.json + unregistered.forEach(key => { + expect(configurationsInPackageJson, 'unregistered settings should not be defined in the package.json').not.toContain(key); }); // Validate Internal settings have the correct prefix @@ -69,13 +91,19 @@ describe('Configurations', () => { }); // Validate public settings in code are in package.json - publicKeys.forEach(key => { - expect(configurationsInPackageJson, 'Setting in code is not defined in the package.json').toContain(key); + otherPublicKeys.forEach(key => { + expect(otherConfigurationsInPackageJson, 'Setting in code is not defined in the package.json').toContain(key); + }); + + // Validate advanced settings in code are in the advanced section of package.json + advancedPublicKeys.forEach(key => { + expect(key, 'Advanced settings must not start wih github.copilot.chat.advanced.').not.toMatch(/^github\.copilot\.chat\.advanced\./); + expect(advancedConfigurationsInPackageJson, `Advanced setting ${key} should be defined in the advanced section of package.json`).toContain(key); }); // Validate settings in package.json are in code configurationsInPackageJson.forEach(key => { - expect(publicKeys, 'Setting in package.json is not defined in code').toContain(key); + expect(registered, 'Setting in package.json is not defined in code').toContain(key); }); }); diff --git a/src/platform/configuration/common/configurationService.ts b/src/platform/configuration/common/configurationService.ts index b90493c45f..7613fe8d32 100644 --- a/src/platform/configuration/common/configurationService.ts +++ b/src/platform/configuration/common/configurationService.ts @@ -669,8 +669,8 @@ export namespace ConfigKey { export const ClaudeCodeDebugEnabled = defineAndMigrateSetting('chat.advanced.claudeCode.debug', 'chat.claudeCode.debug', false); export const CopilotCLIEnabled = defineAndMigrateSetting('chat.advanced.copilotCLI.enabled', 'chat.copilotCLI.enabled', true); export const GitHistoryRelatedFilesUsingEmbeddings = defineAndMigrateSetting('chat.advanced.suggestRelatedFilesFromGitHistory.useEmbeddings', 'chat.suggestRelatedFilesFromGitHistory.useEmbeddings', false); - export const CLIIsolationEnabled = defineAndMigrateSetting('chat.cli.isolation.enabled', 'chat.advanced.cli.isolation.enabled', false); - export const CLIMCPServerEnabled = defineAndMigrateSetting('chat.cli.mcp.enabled', 'chat.advanced.cli.mcp.enabled', false); + export const CLIIsolationEnabled = defineAndMigrateSetting('chat.advanced.cli.isolation.enabled', 'chat.cli.isolation.enabled', false); + export const CLIMCPServerEnabled = defineAndMigrateSetting('chat.advanced.cli.mcp.enabled', 'chat.cli.mcp.enabled', false); // Unused export const EditSourceTrackingShowDecorations = defineAndMigrateSetting('chat.advanced.editSourceTracking.showDecorations', 'chat.editSourceTracking.showDecorations', false); From 4d8376323d68ae6849b6659f058de9b079b933d4 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 14 Nov 2025 15:21:27 +0100 Subject: [PATCH 5/7] fix tests --- .../test/common/configurationService.spec.ts | 56 ++----------------- 1 file changed, 6 insertions(+), 50 deletions(-) diff --git a/src/platform/configuration/test/common/configurationService.spec.ts b/src/platform/configuration/test/common/configurationService.spec.ts index 561fe77c09..dabf93c73c 100644 --- a/src/platform/configuration/test/common/configurationService.spec.ts +++ b/src/platform/configuration/test/common/configurationService.spec.ts @@ -58,224 +58,192 @@ suite('AbstractConfigurationService', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsChat; assert.strictEqual(setting.id, 'chat.projectLabels.chat'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('ProjectLabelsInline is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsInline; assert.strictEqual(setting.id, 'chat.projectLabels.inline'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('ProjectLabelsExpanded is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.ProjectLabelsExpanded; assert.strictEqual(setting.id, 'chat.projectLabels.expanded'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('WorkspaceMaxLocalIndexSize is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceMaxLocalIndexSize; assert.strictEqual(setting.id, 'chat.workspace.maxLocalIndexSize'); assert.strictEqual(setting.defaultValue, 100_000); - assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableFullWorkspace is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableFullWorkspace; assert.strictEqual(setting.id, 'chat.workspace.enableFullWorkspace'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableCodeSearch is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableCodeSearch; assert.strictEqual(setting.id, 'chat.workspace.enableCodeSearch'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, true); }); test('WorkspaceEnableEmbeddingsSearch is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspaceEnableEmbeddingsSearch; assert.strictEqual(setting.id, 'chat.workspace.enableEmbeddingsSearch'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, true); }); test('WorkspacePreferredEmbeddingsModel is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.WorkspacePreferredEmbeddingsModel; assert.strictEqual(setting.id, 'chat.workspace.preferredEmbeddingsModel'); assert.strictEqual(setting.defaultValue, ''); - assert.strictEqual(setting.isPublic, true); }); test('WorkspacePrototypeAdoCodeSearchEndpointOverride is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.WorkspacePrototypeAdoCodeSearchEndpointOverride; assert.strictEqual(setting.id, 'chat.workspace.prototypeAdoCodeSearchEndpointOverride'); assert.strictEqual(setting.defaultValue, ''); - assert.strictEqual(setting.isPublic, true); }); test('FeedbackOnChange is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.FeedbackOnChange; assert.strictEqual(setting.id, 'chat.feedback.onChange'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('ReviewIntent is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.ReviewIntent; assert.strictEqual(setting.id, 'chat.review.intent'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('NotebookSummaryExperimentEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.NotebookSummaryExperimentEnabled; assert.strictEqual(setting.id, 'chat.notebook.summaryExperimentEnabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('NotebookVariableFilteringEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.NotebookVariableFilteringEnabled; assert.strictEqual(setting.id, 'chat.notebook.variableFilteringEnabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('NotebookAlternativeDocumentFormat is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.NotebookAlternativeDocumentFormat; assert.strictEqual(setting.id, 'chat.notebook.alternativeFormat'); assert.strictEqual(setting.defaultValue, AlternativeNotebookFormat.xml); - assert.strictEqual(setting.isPublic, true); }); test('UseAlternativeNESNotebookFormat is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.UseAlternativeNESNotebookFormat; assert.strictEqual(setting.id, 'chat.notebook.alternativeNESFormat.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('TerminalToDebuggerPatterns is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.TerminalToDebuggerPatterns; assert.strictEqual(setting.id, 'chat.debugTerminalCommandPatterns'); assert.deepStrictEqual(setting.defaultValue, []); - assert.strictEqual(setting.isPublic, true); }); test('EditSourceTrackingShowDecorations is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.EditSourceTrackingShowDecorations; assert.strictEqual(setting.id, 'chat.editSourceTracking.showDecorations'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('EditSourceTrackingShowStatusBar is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.EditSourceTrackingShowStatusBar; assert.strictEqual(setting.id, 'chat.editSourceTracking.showStatusBar'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('WorkspaceRecordingEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.WorkspaceRecordingEnabled; assert.strictEqual(setting.id, 'chat.localWorkspaceRecording.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('EditRecordingEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.EditRecordingEnabled; assert.strictEqual(setting.id, 'chat.editRecording.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('TemporalContextMaxAge is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.TemporalContextMaxAge; assert.strictEqual(setting.id, 'chat.temporalContext.maxAge'); assert.strictEqual(setting.defaultValue, 100); - assert.strictEqual(setting.isPublic, true); }); test('TemporalContextPreferSameLang is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.TemporalContextPreferSameLang; assert.strictEqual(setting.id, 'chat.temporalContext.preferSameLang'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('CodeSearchAgentEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.CodeSearchAgentEnabled; assert.strictEqual(setting.id, 'chat.codesearch.agent.enabled'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, true); }); test('AgentTemperature is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.AgentTemperature; assert.strictEqual(setting.id, 'chat.agent.temperature'); assert.strictEqual(setting.defaultValue, undefined); - assert.strictEqual(setting.isPublic, true); }); test('InstantApplyShortModelName is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.InstantApplyShortModelName; assert.strictEqual(setting.id, 'chat.instantApply.shortContextModelName'); assert.strictEqual(setting.defaultValue, 'gpt-4o-instant-apply-full-ft-v66-short'); - assert.strictEqual(setting.isPublic, true); }); test('InstantApplyShortContextLimit is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.InstantApplyShortContextLimit; assert.strictEqual(setting.id, 'chat.instantApply.shortContextLimit'); assert.strictEqual(setting.defaultValue, 8000); - assert.strictEqual(setting.isPublic, true); }); test('EnableUserPreferences is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.EnableUserPreferences; assert.strictEqual(setting.id, 'chat.enableUserPreferences'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('SummarizeAgentConversationHistoryThreshold is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.SummarizeAgentConversationHistoryThreshold; assert.strictEqual(setting.id, 'chat.summarizeAgentConversationHistoryThreshold'); assert.strictEqual(setting.defaultValue, undefined); - assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationMode is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.AgentHistorySummarizationMode; assert.strictEqual(setting.id, 'chat.agentHistorySummarizationMode'); assert.strictEqual(setting.defaultValue, undefined); - assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationWithPromptCache is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.AgentHistorySummarizationWithPromptCache; assert.strictEqual(setting.id, 'chat.agentHistorySummarizationWithPromptCache'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('AgentHistorySummarizationForceGpt41 is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.AgentHistorySummarizationForceGpt41; assert.strictEqual(setting.id, 'chat.agentHistorySummarizationForceGpt41'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('UseResponsesApiTruncation is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.UseResponsesApiTruncation; - assert.strictEqual(setting.id, 'chat.advanced.useResponsesApiTruncation'); + assert.strictEqual(setting.id, 'chat.useResponsesApiTruncation'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); }); @@ -283,14 +251,12 @@ suite('AbstractConfigurationService', () => { const setting = ConfigKey.AdvancedExperimental.OmitBaseAgentInstructions; assert.strictEqual(setting.id, 'chat.omitBaseAgentInstructions'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('PromptFileContext is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.PromptFileContext; - assert.strictEqual(setting.id, 'chat.advanced.promptFileContextProvider.enabled'); + assert.strictEqual(setting.id, 'chat.promptFileContextProvider.enabled'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); }); @@ -298,52 +264,45 @@ suite('AbstractConfigurationService', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.DefaultToolsGrouped; assert.strictEqual(setting.id, 'chat.tools.defaultToolsGrouped'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('VirtualToolEmbeddingRanking is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.VirtualToolEmbeddingRanking; assert.strictEqual(setting.id, 'chat.virtualTools.embeddingRanking'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('MultiReplaceStringGrok is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.MultiReplaceStringGrok; assert.strictEqual(setting.id, 'chat.multiReplaceStringGrok.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, true); }); test('EnableClaudeCodeAgent is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.EnableClaudeCodeAgent; - assert.strictEqual(setting.id, 'chat.advanced.claudeCode.enabled'); + assert.strictEqual(setting.id, 'chat.claudeCode.enabled'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); }); test('ClaudeCodeDebugEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.ClaudeCodeDebugEnabled; - assert.strictEqual(setting.id, 'chat.advanced.claudeCode.debug'); + assert.strictEqual(setting.id, 'chat.claudeCode.debug'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); }); test('CopilotCLIEnabled is correctly configured', () => { const setting = ConfigKey.AdvancedExperimental.CopilotCLIEnabled; - assert.strictEqual(setting.id, 'chat.advanced.copilotCLI.enabled'); + assert.strictEqual(setting.id, 'chat.copilotCLI.enabled'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, false); }); test('Gpt5AlternativePatch is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.Gpt5AlternativePatch; - assert.strictEqual(setting.id, 'chat.advanced.gpt5AlternativePatch'); + assert.strictEqual(setting.id, 'chat.gpt5AlternativePatch'); assert.strictEqual(setting.defaultValue, false); - assert.strictEqual(setting.isPublic, false); }); @@ -353,21 +312,18 @@ suite('AbstractConfigurationService', () => { const defaultValue = setting.defaultValue as DefaultValueWithTeamValue; assert.strictEqual(defaultValue.defaultValue, undefined); assert.strictEqual(defaultValue.teamDefaultValue, 10); - assert.strictEqual(setting.isPublic, true); }); test('InlineEditsNextCursorPredictionDisplayLine is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.InlineEditsNextCursorPredictionDisplayLine; assert.strictEqual(setting.id, 'chat.inlineEdits.nextCursorPrediction.displayLine'); assert.strictEqual(setting.defaultValue, true); - assert.strictEqual(setting.isPublic, true); }); test('InlineEditsNextCursorPredictionCurrentFileMaxTokens is correctly configured', () => { const setting = ConfigKey.AdvancedExperimentalExperiments.InlineEditsNextCursorPredictionCurrentFileMaxTokens; assert.strictEqual(setting.id, 'chat.inlineEdits.nextCursorPrediction.currentFileMaxTokens'); assert.strictEqual(setting.defaultValue, 2000); - assert.strictEqual(setting.isPublic, true); }); }); From 93a2923c85557170f26b33ffe38565f32b50b5d4 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 14 Nov 2025 17:42:00 +0100 Subject: [PATCH 6/7] Add backward support for the pattern used in older experiments --- .../configuration/vscode/configurationServiceImpl.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/platform/configuration/vscode/configurationServiceImpl.ts b/src/platform/configuration/vscode/configurationServiceImpl.ts index 474d7d1c20..04ee2e4cfd 100644 --- a/src/platform/configuration/vscode/configurationServiceImpl.ts +++ b/src/platform/configuration/vscode/configurationServiceImpl.ts @@ -220,10 +220,15 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { } if (key.fullyQualifiedOldId) { - const oldExpValue = experimentationService.getTreatmentVariable>(`config.${key.fullyQualifiedOldId}`); + const oldExpValue = experimentationService.getTreatmentVariable>(`copilotchat.config.${key.fullyQualifiedOldId}`); if (oldExpValue !== undefined) { return oldExpValue; } + + const oldExpValue2 = experimentationService.getTreatmentVariable>(`config.${key.fullyQualifiedOldId}`); + if (oldExpValue2 !== undefined) { + return oldExpValue2; + } } return this.getDefaultValue(key); From 28cee278b2e9d9239b3ba6e92f89879b46afd847 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 14 Nov 2025 17:53:36 +0100 Subject: [PATCH 7/7] fix id --- src/platform/configuration/vscode/configurationServiceImpl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/configuration/vscode/configurationServiceImpl.ts b/src/platform/configuration/vscode/configurationServiceImpl.ts index 04ee2e4cfd..96f44394a8 100644 --- a/src/platform/configuration/vscode/configurationServiceImpl.ts +++ b/src/platform/configuration/vscode/configurationServiceImpl.ts @@ -220,7 +220,7 @@ export class ConfigurationServiceImpl extends AbstractConfigurationService { } if (key.fullyQualifiedOldId) { - const oldExpValue = experimentationService.getTreatmentVariable>(`copilotchat.config.${key.fullyQualifiedOldId}`); + const oldExpValue = experimentationService.getTreatmentVariable>(`copilotchat.config.${key.oldId}`); if (oldExpValue !== undefined) { return oldExpValue; }