-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Navigating the codebase like a developer: f12/symbolic navigation tools #2105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Navigating the codebase like a developer: f12/symbolic navigation tools #2105
Conversation
@microsoft-github-policy-service agree [company="{Microsoft}"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces symbolic navigation tools that enable the AI to navigate codebases like a developer using F12-style navigation (Go to Definition, Find References, Find Implementations) along with document symbol listing capabilities.
Key Changes
- Added four new language model tools:
DocumentSymbols,Definitions,Implementations, andReferences - Implemented shared utilities for symbol position normalization and ambiguity resolution
- Updated agent prompts to instruct the AI on when and how to use symbolic navigation tools
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
src/extension/tools/node/definitionsTool.tsx |
New tool implementing "Go to Definition" functionality with symbol disambiguation |
src/extension/tools/node/implementationsTool.tsx |
New tool for finding concrete implementations of interfaces/abstract members |
src/extension/tools/node/referencesTool.tsx |
New tool for finding all references to a symbol across the workspace |
src/extension/tools/node/documentSymbolsTool.tsx |
New tool for listing document symbols with pagination and caching support |
src/extension/tools/node/toolUtils.ts |
Added shared utilities for symbol position normalization and disambiguation |
src/extension/tools/node/allTools.ts |
Registered the four new navigation tools |
src/extension/tools/common/toolNames.ts |
Added enum entries and tool categories for the new tools |
src/extension/tools/vscode-node/tools.ts |
Added debug logging for tool registration |
src/extension/prompts/node/panel/codebaseAgentPrompt.tsx |
Added instructions for using symbolic navigation tools in codebase agent |
src/extension/prompts/node/agent/defaultAgentInstructions.tsx |
Added instructions for symbolic navigation in default and alternate GPT prompts |
package.json |
Added JSON schemas for the four new tools with complete parameter definitions |
package.nls.json |
Added localized strings for tool names and descriptions |
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | ||
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | ||
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sentence starts with lowercase "you" after a period. It should be capitalized: "You must use the line number..."
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. You must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. You must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. Very useful when modifying public functions signatures or data structures. You must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> |
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | ||
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | ||
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sentence starts with lowercase "you" after a period. It should be capitalized: "You must use the line number..."
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. You must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. You must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. Very useful when modifying public functions signatures or data structures. You must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> |
| } | ||
|
|
||
| function normalizeLocations(locations: readonly (vscode.Location | vscode.LocationLink)[]): Location[] { | ||
| return locations.map(location => location instanceof Location ? location : new Location(location.targetUri, location.targetSelectionRange ?? location.targetRange)); |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The instanceof Location check may not work correctly. Since Location is imported from the vscode API, checking instanceof may fail when the location comes from a different execution context. Consider checking for the presence of expected properties instead: 'uri' in location && 'range' in location or use a type guard.
| return locations.map(location => location instanceof Location ? location : new Location(location.targetUri, location.targetSelectionRange ?? location.targetRange)); | |
| return locations.map(location => ('uri' in location && 'range' in location) ? location : new Location(location.targetUri, location.targetSelectionRange ?? location.targetRange)); |
| Use {ToolName.DocumentSymbols} After you have a likely file, call {ToolName.DocumentSymbols} to review its structure, and get accurate symbols and their line numbers for further navigation. Page through results with the "page" and "pageSize" options, or set "reset": true to rebuild the cache before paging. <br /> | ||
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | ||
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | ||
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sentence "very useful when modifying..." should start with a capital letter: "Very useful when modifying..."
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> | |
| Call {ToolName.References} to find referenced usages of a symbol across the codeobase. Very useful when modifying public functions signatures or data structures. you must use the line number and symbol name as received from the {ToolName.DocumentSymbols} tool.<br /> |
| const extensionVersion = vscode.extensions.getExtension('github.copilot-chat')?.packageJSON?.version; | ||
| console.log(`[CopilotTools] registering tools for github.copilot-chat@${extensionVersion ?? 'unknown'}`); | ||
|
|
||
| for (const [name, tool] of toolsService.copilotTools) { | ||
| console.log(`[CopilotTools] registering ${name}`); |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug console.log statements should be removed or replaced with proper logging using the project's logging infrastructure. The extension should use the logging service from src/extension/log/ instead of console.log for production code.
| Use {ToolName.Codebase} to search for high level concepts or descriptions of functionality in the user's question. This is the best place to start if you don't know where to look or the exact strings found in the codebase.<br /> | ||
| Always prefer symbolic navigation when applicable. | ||
| Use {ToolName.DocumentSymbols} After you have a likely file, call {ToolName.DocumentSymbols} to review its structure. Page through results with the "page" and "pageSize" options, or set "reset": true to rebuild the cache before paging. <br /> | ||
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12.<br /> |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing line break. According to the TSX coding guidelines, <br /> should be used for line breaks. Add <br /> at the end of this line to properly separate it from the next instruction.
| Always prefer symbolic navigation when applicable. | ||
| Use {ToolName.DocumentSymbols} After you have a likely file, call {ToolName.DocumentSymbols} to review its structure. Page through results with the "page" and "pageSize" options, or set "reset": true to rebuild the cache before paging. <br /> | ||
| Use {ToolName.Definitions} When you know where you are in the file, use {ToolName.Definitions} to navigate straight to the target symbol, just like a developer would use f12.<br /> | ||
| Call {ToolName.Implementations} to enumerate concrete implementations when working or modifying with interfaces and you need to recognize their usages<br /> |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing line break. According to the TSX coding guidelines, <br /> should be used for line breaks. Add <br /> at the end of this line to properly separate it from the next instruction.
| ] | ||
| } | ||
| }, | ||
| { |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation. According to the coding guidelines, tabs should be used for indentation. This line uses tabs but is misaligned with the surrounding code. The opening brace should align with the lines above it at lines 224 and 267.
| function normalizeLocations(locations: readonly (vscode.Location | vscode.LocationLink)[]): Location[] { | ||
| return locations.map(location => location instanceof Location ? location : new Location(location.targetUri, location.targetSelectionRange ?? location.targetRange)); |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The instanceof Location check may not work correctly. Since Location is imported from the vscode API, checking instanceof may fail when the location comes from a different execution context. Consider checking for the presence of expected properties instead: 'uri' in location && 'range' in location or use a type guard.
| function normalizeLocations(locations: readonly (vscode.Location | vscode.LocationLink)[]): Location[] { | |
| return locations.map(location => location instanceof Location ? location : new Location(location.targetUri, location.targetSelectionRange ?? location.targetRange)); | |
| function isLocation(obj: any): obj is Location { | |
| return obj && typeof obj === 'object' && 'uri' in obj && 'range' in obj; | |
| } | |
| function normalizeLocations(locations: readonly (vscode.Location | vscode.LocationLink)[]): Location[] { | |
| return locations.map(location => | |
| isLocation(location) | |
| ? location | |
| : new Location(location.targetUri, location.targetSelectionRange ?? location.targetRange) | |
| ); |
| */ | ||
| export class CodesearchModeInstructions extends PromptElement<DefaultAgentPromptProps> { | ||
| render(state: void, sizing: PromptSizing) { | ||
| const tools = detectToolCapabilities(this.props.availableTools); |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused variable tools.
| const tools = detectToolCapabilities(this.props.availableTools); |
|
@OmerMachluf please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
This is an exploration PR: It is not fully ready yet.
The core idea behind it is to reduce the number of text searches which are expensive, yield many results and limit the capability to work properly in big/huge repositories.
Instead, this aims to provide tools for copilot that allows him to navigate the codebase like a developer would.
It leverages LSP to provide code referneces, f12 capability, find references/implementations etc or get the document full symbols to understand structure and allow to focus on which lines to read beforehand.
I haven't done official benchmarking yet(And I was curious if there are any suites already designed for that purpose), but from my own internal tests I am able to complete tasks that would have usually yielded or give up due to context loss or too many searches yielding nothing.
Execution happens faster and more realibly as the copilot simply navigates between documents he's exploring or modifying using semantic references.
I wanted to get a ack that there are no blockers with this approach before doubling down on the time allocated to complete this fully.
Among the gaps that I currently recognize are: