diff --git a/extensions/copilot/package.json b/extensions/copilot/package.json index a2a7327916c6ef..bbc2f120472b1c 100644 --- a/extensions/copilot/package.json +++ b/extensions/copilot/package.json @@ -4170,6 +4170,15 @@ "onExp" ] }, + "github.copilot.chat.claudeSonnet5Prompt.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.claudeSonnet5Prompt.enabled%", + "tags": [ + "experimental", + "onExp" + ] + }, "github.copilot.chat.gpt55GetChangedFilesTool.enabled": { "type": "boolean", "default": true, diff --git a/extensions/copilot/package.nls.json b/extensions/copilot/package.nls.json index eb4b70f1761dba..4abb2b478062a2 100644 --- a/extensions/copilot/package.nls.json +++ b/extensions/copilot/package.nls.json @@ -352,6 +352,7 @@ "github.copilot.config.responsesApi.promptCacheBreakpoint.enabled": "Enables explicit prompt cache breakpoint markers for the Responses API.", "github.copilot.config.updated53CodexPrompt.enabled": "Enables the updated prompt for gpt-5.3-codex model.", "github.copilot.config.claudeOpus5Prompt.enabled": "Enables the updated system prompt tuned for the Claude Opus 5 model.", + "github.copilot.config.claudeSonnet5Prompt.enabled": "Enables the updated system prompt tuned for the Claude Sonnet 5 model.", "github.copilot.config.gpt55GetChangedFilesTool.enabled": "Enables the Get Changed Files tool for gpt-5.5 models.", "github.copilot.config.gpt56Verbosity.enabled": "Sets the response verbosity to low for gpt-5.6 models.", "github.copilot.config.gemini3GetChangedFilesTool.enabled": "Enables the Get Changed Files tool for gemini-3 models.", diff --git a/extensions/copilot/src/extension/prompts/node/agent/anthropicPrompts.tsx b/extensions/copilot/src/extension/prompts/node/agent/anthropicPrompts.tsx index b6869965460081..d69c0d32d9afe1 100644 --- a/extensions/copilot/src/extension/prompts/node/agent/anthropicPrompts.tsx +++ b/extensions/copilot/src/extension/prompts/node/agent/anthropicPrompts.tsx @@ -422,6 +422,25 @@ class Claude46SonnetPrompt extends Claude46OptimizedBasePrompt { } } +/** + * Prompt for Claude Sonnet 5, extending the optimized Sonnet 4.6 prompt with a scope-discipline + * paragraph. Sonnet 5 explores and explains more than Sonnet 4.6 on the same task, which raises + * both its score and its token cost. Constraining scope alone regresses cases where a backwards + * compatibility shim looks like adjacent work, so the interface-preservation clause is required + * alongside it. + */ +class ClaudeSonnet5Prompt extends Claude46SonnetPrompt { + protected override renderAppendedInstructions() { + return + Do exactly what was asked - don't extend scope to new adjacent code, tests, examples, or unrelated files unless the task explicitly includes them.
+ But always preserve existing public interfaces: never remove or change the signature of module-level functions, exported names, or class methods that other code might depend on, unless explicitly told to.
+ If you think adjacent work is needed, mention it rather than doing it.
+ Be direct and minimal on file reads and editor-tool calls; spend your reasoning on design decisions, debugging, and writing code.
+ Keep your responses to the user concise - a few sentences explaining what you did and why is enough; the work happens in tool calls, not in prose.
+
; + } +} + /** Opus-specific optimized prompt for Claude 4.6. */ class Claude46OpusPrompt extends Claude46OptimizedBasePrompt { protected override renderExplorationGuidance(_tools: ReturnType) { @@ -541,6 +560,10 @@ class AnthropicPromptResolver implements IAgentPrompt { return endpoint.model.startsWith('claude-sonnet') || endpoint.family.startsWith('claude-sonnet'); } + private isSonnet5(endpoint: IChatEndpoint): boolean { + return endpoint.model.startsWith('claude-sonnet-5') || endpoint.family.startsWith('claude-sonnet-5'); + } + private isHaiku(endpoint: IChatEndpoint): boolean { return endpoint.model.startsWith('claude-haiku') || endpoint.family.startsWith('claude-haiku'); } @@ -556,6 +579,9 @@ class AnthropicPromptResolver implements IAgentPrompt { if (this.isClaude45(endpoint)) { return Claude45DefaultPrompt; } + if (this.isSonnet5(endpoint) && this.configurationService.getExperimentBasedConfig(ConfigKey.ClaudeSonnet5PromptEnabled, this.experimentationService)) { + return ClaudeSonnet5Prompt; + } if (this.isSonnet(endpoint)) { return Claude46SonnetPrompt; } diff --git a/extensions/copilot/src/platform/configuration/common/configurationService.ts b/extensions/copilot/src/platform/configuration/common/configurationService.ts index e1a917b25dff50..6bb768ec171020 100644 --- a/extensions/copilot/src/platform/configuration/common/configurationService.ts +++ b/extensions/copilot/src/platform/configuration/common/configurationService.ts @@ -982,6 +982,8 @@ export namespace ConfigKey { export const Updated53CodexPromptEnabled = defineSetting('chat.updated53CodexPrompt.enabled', ConfigType.ExperimentBased, true); /** Enable updated prompt for Claude Opus 5 model */ export const ClaudeOpus5PromptEnabled = defineSetting('chat.claudeOpus5Prompt.enabled', ConfigType.ExperimentBased, false); + /** Enable updated prompt for Claude Sonnet 5 model */ + export const ClaudeSonnet5PromptEnabled = defineSetting('chat.claudeSonnet5Prompt.enabled', ConfigType.ExperimentBased, false); /** Enable get_changed_files tool for GPT-5.5 models */ export const EnableGpt55GetChangedFilesTool = defineSetting('chat.gpt55GetChangedFilesTool.enabled', ConfigType.ExperimentBased, true); /** Enable low verbosity for GPT-5.6 models. */