debugging/evals: allow static overrides of system prompts and tooldescriptions#3959
debugging/evals: allow static overrides of system prompts and tooldescriptions#3959
Conversation
… YAML file Adds a new advanced debug setting `github.copilot.chat.advanced.debug.promptOverrideFile` that allows specifying a YAML file to override the system prompt and/or tool descriptions sent to the model at runtime. This enables prompt engineering and debugging without modifying source code. The override is applied in toolCallingLoop.ts before the debug view event fires, so the chat debug view reflects the actual overridden content. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
59f1e76 to
99a554f
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new advanced debugging capability to override the runtime system prompt and tool descriptions via a user-provided YAML file, enabling prompt/tool experimentation without rebuilding the extension.
Changes:
- Adds new advanced setting
github.copilot.chat.debug.promptOverrideFile(with migration from legacy key). - Introduces
applyPromptOverrides()to read/parse YAML and apply system/tool overrides. - Integrates the override application into the tool-calling loop prior to the “prompt built” event, and adds unit tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/platform/configuration/common/configurationService.ts | Defines a migrated advanced config key for chat.debug.promptOverrideFile. |
| package.json | Registers the new advanced setting in VS Code settings UI. |
| src/extension/intents/node/promptOverride.ts | Implements YAML-based overrides for system prompt and tool descriptions. |
| src/extension/intents/node/toolCallingLoop.ts | Applies overrides at runtime before firing _onDidBuildPrompt. |
| src/extension/intents/node/test/promptOverride.spec.ts | Adds unit coverage for override behavior and error handling. |
| try { | ||
| const content = await fs.readFile(filePath, 'utf-8'); | ||
| config = yaml.load(content) as PromptOverrideConfig; | ||
| } catch (err) { | ||
| logService.warn(`[PromptOverride] Failed to read or parse YAML file "${filePath}": ${err}`); | ||
| return { messages: [...messages], tools: [...tools] }; |
There was a problem hiding this comment.
applyPromptOverrides logs a warning on every request when the configured file can’t be read/parsed (e.g., missing file). Since this file is re-read for every chat request, a misconfiguration can quickly spam logs. Consider throttling/deduplicating this warning per filePath (or logging once and then switching to trace until the config changes).
| import { Raw } from '@vscode/prompt-tsx'; | ||
| import { promises as fs } from 'fs'; | ||
| import * as yaml from 'js-yaml'; | ||
| import type { LanguageModelToolInformation } from 'vscode'; | ||
| import { ILogService } from '../../../platform/log/common/logService'; |
There was a problem hiding this comment.
This reads the override file via Node's fs and a raw string path. In this repo, file access is typically routed through IFileSystemService with URI to keep code testable and consistent across environments (and avoid module-level fs mocking). Consider switching filePath to a URI (or parsing to URI.file(...)) and reading via IFileSystemService.readFile instead of fs.promises.readFile.
| buildPromptResult.messages, | ||
| availableTools, | ||
| this._logService, | ||
| ); | ||
| (buildPromptResult as { messages: Raw.ChatMessage[] }).messages = overrideResult.messages; | ||
| availableTools = overrideResult.tools; |
There was a problem hiding this comment.
Avoid mutating buildPromptResult via a type-cast assignment. IBuildPromptResult is treated as an immutable render result elsewhere, and this cast makes it easy to miss that later code is using overridden messages. Prefer creating a new effectiveBuildPromptResult (e.g., { ...buildPromptResult, messages: overrideResult.messages }) and use that for token counting, _onDidBuildPrompt.fire, and ResponseProcessorContext construction.
|
@copilot open a new pull request to apply changes based on the comments in this thread |
Summary
Adds a new advanced debug setting
github.copilot.chat.debug.promptOverrideFilethat allows specifying a YAML file to override the system prompt and/or tool descriptions sent to the model at runtime.This enables prompt engineering and debugging without modifying source code or rebuilding.
Screenshot
How it works
The override is applied in
toolCallingLoop.tsafter prompt rendering but before the_onDidBuildPromptevent fires, so the Chat Debug View reflects the actual overridden content sent to the model.The YAML file is re-read on every request — changes take effect immediately without reloading VS Code.
When the setting is not configured, the code path is completely skipped (no file reads, no array copies, no overhead).
Usage
1. Create a YAML override file
2. Configure the setting
Or search for
promptOverrideFilein the Settings UI (taggedadvanced/experimental).3. Common tool names for
toolDescriptionsread_filelist_dirgrep_searchfile_searchsemantic_searchapply_patchget_errorsget_changed_filesError handling
toolDescriptions→ silently ignoredChanges
configurationService.tsDebugPromptOverrideFilesetting inAdvancednamespacepackage.jsonpromptOverride.ts(new)toolCallingLoop.tspromptOverride.spec.ts(new)