* chat: require confirmation for .mcp.json edits
Updates edit approval patterns so edits to `.mcp.json` require user confirmation in both edit execution paths.
- Adds `.mcp.json` to the standard chat edit confirmation patterns.
- Adds `.mcp.json` to the agent host edit confirmation patterns.
- Extends focused tests for both edit execution paths.
(Commit message generated by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* agentHost: test .mcp.json path casing
Adds `.mcp.json` to the existing non-canonical casing coverage for protected edit paths.
(Commit message generated by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* chat: always confirm .npmrc edits
Treat .npmrc files as non-overridable protected edit targets in both chat approval paths, with root and nested-path coverage.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce a WorkingDirectory class that encapsulates the "use explicit
working directory if set, otherwise fall back to workspace folders" logic.
This replaces the pattern of passing a raw workingDirectory URI alongside
IWorkspaceService throughout tools, prompts, and confirmation helpers.
- Extension side: WorkingDirectory in platform/workspace/common/ uses
@IWorkspaceService DI injection
- VS Code core side: WorkingDirectory in chat/common/ wraps
IWorkspaceContextService
- Refactored inputGlobToPattern, assertFileOkForTool,
isFileExternalAndNeedsConfirmation, isDirExternalAndNeedsConfirmation,
createEditConfirmation, and resolveToolUri to use WorkingDirectory
- Updated prompt components (WorkspaceFoldersHint,
MultirootWorkspaceStructure) and tool implementations
(findFiles, findTextInFiles, searchSubagent, fetchPage)
In the agents window, each chat session has its own working directory
that may differ from the current workspace folders (which change when
switching between sessions). This caused tools to search the wrong
folder, show spurious 'Allow reading external files?' prompts, and
render incorrect workspace_info in the system prompt.
Core plumbing:
- Add workingDirectory to IToolInvocationContext, IToolInvocationPreparationContext,
ILanguageModelToolConfirmationRef, and IChatAgentRequest
- Enrich tool invocation context from model.workingDirectory in invokeTool()
- Include workingDirectory in toolInvocationToken built in extHostTypeConverters
- Pass workingDirectory through LanguageModelToolInvocationOptions and
LanguageModelToolInvocationPrepareOptions (proposed API)
- Revive workingDirectory URI in extHostLanguageModelTools
Tool fixes (when workingDirectory is set, use it exclusively):
- chatExternalPathConfirmation: auto-approve paths within workingDirectory
- isFileExternalAndNeedsConfirmation / isDirExternalAndNeedsConfirmation /
assertFileOkForTool: treat workingDirectory as workspace-internal
- createEditConfirmation: use workingDirectory for edit trust checks
- All edit tools (create_file, replace_string, multi_replace, apply_patch,
insert_edit, edit_notebook, create_directory): pass workingDirectory
- resolveToolUri: resolve relative paths against workingDirectory
- inputGlobToPattern: scope unscoped globs to workingDirectory
- file_search / grep_search: scope searches to workingDirectory
- semantic_search: prefer workingDirectory for cwd
- run_in_terminal: prefer workingDirectory for terminal cwd
- fetchPageTool: check workingDirectory for file URI trust
- readFileTool / listDirTool / viewImageTool: pass workingDirectory
Prompt fixes:
- WorkspaceFoldersHint: show workingDirectory instead of workspace folders
- AgentMultirootWorkspaceStructure: generate file tree from workingDirectory
Use backticks for proper template literal interpolation of ${ToolName.ReadFile}.
Fix duplicate 'and and' → 'and'.
Import ToolName from registry so message stays in sync if tool name changes.
Addresses Copilot AI review feedback: keeps tool name in sync with registry.
Improves file edit confirmation notifications by skipping diff display
when the only difference between old and new content is whitespace. This
prevents showing overly large diffs (e.g., >2500 lines) when the actual
changes are minimal or non-existent, making it clearer to users what
changes the agent is making.
- Adds early return in formatDiffAsUnified when content is identical
after trimming whitespace
- Displays a brief 'contents are identical' message instead of a large
diff
Fixes https://github.com/microsoft/vscode/issues/288781
(Commit message generated by Copilot)
* tools: add support for model-specific tool registration
This PR goes with https://github.com/microsoft/vscode/pull/287666
This allows the registration of tools that are scoped to specific
language models. These tools can be registered at runtime with
definitions derived from e.g. the server.
I think we should adopt this and go away from the current
`alternativeDefinitions` pattern which we have used previously.
Example of having tools specific for GPT 4.1 vs 4o:
```ts
ToolRegistry.registerModelSpecificTool(
{
name: 'gpt41_get_time',
inputSchema: {},
description: 'Get the current date and time (4.1)',
displayName: 'Get Time (GPT 4.1)',
toolReferenceName: 'get_time',
source: undefined,
tags: [],
models: [{ id: 'gpt-4.1' }],
},
class implements ICopilotTool<unknown> {
invoke() {
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart('Current year is 2041 (GPT 4.1)')]);
}
}
);
ToolRegistry.registerModelSpecificTool(
{
name: 'gpt4o_get_time',
inputSchema: {},
description: 'Get the current date and time (4o)',
displayName: 'Get Time (GPT 4o)',
toolReferenceName: 'get_time',
source: undefined,
tags: [],
models: [{ id: 'gpt-4o' }],
},
class implements ICopilotTool<unknown> {
invoke() {
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart('Current year is 2040 (GPT 4o)')]);
}
}
);
```
* demo
* fix
* overrides
* add overridesTool
* fix inverted logic
* test fixes and back compat
* make memory tool model specific
* fix tests and contribute memory to the vscode toolset
* verison
* fix unit tests
* rm config
* fix missing askquestions
---------
Co-authored-by: bhavyaus <bhavyau@microsoft.com>
Enables the same `no-unexternalized-strings` with have in `vscode` in this repo. This make sure we have a more consistent style across repos and when generating edits
* edits: fix conflicting edits in multi-replace-string
- Minimize identical content in text edits to avoid potential conflicts in context
- Explicitly error any edits that still fail rather than garbling the file
Closes https://github.com/microsoft/vscode/issues/277154
* rm test.only
* fix whitespaces not being preserved in ws flex match
This fixes a race condition that can happen in LM results that contain
multiple edit tool calls. The emission and application of edits is
async, and so it is possible that an edit can be emitted and the next
edit generated before the first edit's changes are propagated to the
extension host's model.
This resolves the issue by keeping, updating, and reusing snapshotted
documents on each turn's prompt context.
cc @DonJayamanne for notebook stuff. This is a little shakier but it
seems to work (and I know NB prefers the separate notebook edit tool
anyway.)
The similarity matching in the replace_string tool incorrect was using
line numbers rather than string offsets (since inception!) which caused
file corruption issues. I initially thought it was only in the multi
edit tool, but it happens in all replace_string variants.
Closes https://github.com/microsoft/vscode/issues/265842
- Don't block edits to files outside the workspace, but allow them with
confirmations.
- Always confirm on certain files (dotfiles/folders in the home
directory and appdatas on Windows)
After talking to Kai, we decided that the rare case of sensitive files edits should just use our standard confirmation UI instead of adding more variances to the base chat experience.
* test implementation of gemini-inspired model based healing
* rationalize types in string replace tools
* cleanup and add telemetry for string_replace healing
* prompting improvements
* add failsafe for string-replace healing
* update snapshot