-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Built-in toolsets for default tools #1139
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
Open
24anisha
wants to merge
15
commits into
microsoft:main
Choose a base branch
from
24anisha:anisha/default_toolsets
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+233
−25
Open
Changes from 13 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
8f4b748
adding starting changes for tool selection from default toolset
d878d19
update code to have all current default tools in groups (or ungrouped…
ab16c1f
update max tools
422b3a5
small changes
9c600ac
separate logic for built in tool grouping to new file
9b2a91f
remove unnecessary telemetry sending
f66be55
adding intermediate changes
5d44c99
Merge branch 'main' into anisha/default_toolsets
6741dc8
updated explicit tool set
5affdde
Merge branch 'main' into anisha/default_toolsets
24anisha 125db45
Merge branch 'main' into anisha/default_toolsets
2031717
only perform grouping for gpt 4.1 and 5
74b7a7a
updated the hard tool limit back to 128, added logic
8523fba
Merge branch 'main' into anisha/default_toolsets
24anisha b3a53dd
Apply suggestion from @Copilot
24anisha File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
src/extension/tools/common/virtualTools/builtInToolGroupHandler.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
import type { LanguageModelToolInformation } from 'vscode'; | ||
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry'; | ||
import { VIRTUAL_TOOL_NAME_PREFIX, VirtualTool } from './virtualTool'; | ||
import * as Constant from './virtualToolsConstants'; | ||
|
||
const BUILT_IN_GROUP = 'builtin'; | ||
const SUMMARY_PREFIX = 'Call this tool when you need access to a new category of tools. The category of tools is described as follows:\n\n'; | ||
const SUMMARY_SUFFIX = '\n\nBe sure to call this tool if you need a capability related to the above.'; | ||
|
||
// categorize all tools except for the 12 default tools | ||
// 12 default tools = semantic_search, grep_search, read_file, create_file, apply_patch, replace_string_in_file, | ||
// insert_edit_into_file, run_in_terminal, list_dir, think, get_terminal_output, manage_todo_list | ||
const BUILT_IN_TOOL_GROUPS = { | ||
'Jupyter Notebook Tools': { | ||
summary: 'Call tools from this group when you need to work with Jupyter notebooks - creating, editing, running cells, and managing notebook operations.', | ||
tools: [ | ||
'create_new_jupyter_notebook', | ||
'edit_notebook_file', | ||
'run_notebook_cell', | ||
'copilot_getNotebookSummary', | ||
'read_notebook_cell_output', | ||
'configure_notebook', | ||
'notebook_install_packages', | ||
'notebook_list_packages', | ||
'configure_python_environment', | ||
'get_python_environment_details', | ||
'get_python_executable_details' | ||
] | ||
}, | ||
'Web Interaction': { | ||
summary: 'Call tools from this group when you need to interact with web content, browse websites, or access external resources.', | ||
tools: [ | ||
'fetch_webpage', | ||
'open_simple_browser', | ||
'github_repo' | ||
] | ||
}, | ||
'VS Code Interaction': { | ||
summary: 'Call tools from this group when you need to interact with the VS Code workspace and access VS Code features.', | ||
tools: [ | ||
'search_workspace_symbols', | ||
'list_code_usages', | ||
'get_errors', | ||
'get_vscode_api', | ||
'get_changed_files', | ||
'create_new_workspace', | ||
'install_extension', | ||
'get_project_setup_info', | ||
'create_and_run_task', | ||
'run_task', | ||
'get_task_output', | ||
'run_vscode_command', | ||
'install_python_packages', | ||
'get_search_view_results', | ||
'vscode_searchExtensions_internal', | ||
'read_project_structure' | ||
] | ||
}, | ||
'Testing': { | ||
summary: 'Call tools from this group when you need to run tests, analyze test failures, and manage test workflows.', | ||
tools: [ | ||
'run_tests', | ||
'test_failure', | ||
'test_search', | ||
'runTests' | ||
] | ||
}, | ||
'Redundant but Specific': { | ||
summary: 'These tools have overlapping functionalities but are highly specialized for certain tasks. \nTools: file_search, terminal_selection, terminal_last_command, create_directory, get_doc_info, multi_replace_string_in_file, edit_files', | ||
tools: [ | ||
'file_search', | ||
'terminal_selection', | ||
'terminal_last_command', | ||
'create_directory', | ||
'get_doc_info', | ||
'edit_files', | ||
'multi_replace_string_in_file' | ||
] | ||
} | ||
} as const; | ||
|
||
export class BuiltInToolGroupHandler { | ||
constructor( | ||
private readonly _telemetryService: ITelemetryService, | ||
) { } | ||
|
||
/** Creates groups for built-in tools based on the pre-defined enum above*/ | ||
createBuiltInToolGroups(tools: LanguageModelToolInformation[]): (VirtualTool | LanguageModelToolInformation)[] { | ||
// If there are too few tools, don't group them | ||
if (tools.length <= Constant.MIN_TOOLSET_SIZE_TO_GROUP) { | ||
return tools; | ||
} | ||
|
||
const toolMap = new Map(tools.map(tool => [tool.name, tool])); | ||
|
||
const virtualTools: VirtualTool[] = []; | ||
const usedTools = new Set<string>(); | ||
|
||
// Create virtual tools for each predefined group | ||
for (const [groupName, groupDef] of Object.entries(BUILT_IN_TOOL_GROUPS)) { | ||
const groupTools = groupDef.tools | ||
.map(toolName => toolMap.get(toolName)) | ||
.filter((tool): tool is LanguageModelToolInformation => tool !== undefined); | ||
|
||
if (groupTools.length > 0) { | ||
// Mark each tool that has already been added to a group | ||
groupTools.forEach(tool => usedTools.add(tool.name)); | ||
|
||
const virtualTool = new VirtualTool( | ||
VIRTUAL_TOOL_NAME_PREFIX + groupName.toLowerCase().replace(/\s+/g, '_'), | ||
SUMMARY_PREFIX + groupDef.summary + SUMMARY_SUFFIX, | ||
0, | ||
{ | ||
toolsetKey: BUILT_IN_GROUP, | ||
groups: [], | ||
possiblePrefix: 'builtin_' | ||
}, | ||
groupTools | ||
); | ||
virtualTools.push(virtualTool); | ||
} | ||
} | ||
|
||
// Add any remaining uncategorized tools individually | ||
const uncategorizedTools = tools.filter(tool => !usedTools.has(tool.name)); | ||
|
||
// Send telemetry for built-in tool grouping | ||
this._telemetryService.sendMSFTTelemetryEvent('virtualTools.generate', { | ||
groupKey: BUILT_IN_GROUP, | ||
}, { | ||
uncategorized: uncategorizedTools.length, | ||
toolsBefore: tools.length, | ||
toolsAfter: virtualTools.length, | ||
retries: 0, // No retries for predefined groups | ||
durationMs: 0, // Instant for predefined groups | ||
}); | ||
|
||
return [...virtualTools, ...uncategorizedTools]; | ||
} | ||
|
||
static get BUILT_IN_GROUP_KEY(): string { | ||
return BUILT_IN_GROUP; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
|
||
import type { LanguageModelToolInformation } from 'vscode'; | ||
import { ConfigKey, HARD_TOOL_LIMIT, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; | ||
import { IChatEndpoint } from '../../../../platform/networking/common/networking'; | ||
import { IExperimentationService } from '../../../../platform/telemetry/common/nullExperimentationService'; | ||
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry'; | ||
import { equals as arraysEqual, uniqueFilter } from '../../../../util/vs/base/common/arrays'; | ||
|
@@ -47,7 +48,13 @@ export class ToolGrouping implements IToolGrouping { | |
} | ||
|
||
public get isEnabled() { | ||
return this._tools.length >= computeToolGroupingMinThreshold(this._experimentationService, this._configurationService).get(); | ||
// Match the logic from VirtualToolGrouper.addGroups() | ||
// Enable if we could potentially trigger built-in grouping (when GPT model is used) | ||
const defaultToolGroupingEnabled = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.DefaultToolsGrouped, this._experimentationService); | ||
const couldTriggerBuiltInGrouping = this._tools.length > Constant.START_BUILTIN_GROUPING_AFTER_TOOL_COUNT && defaultToolGroupingEnabled; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't check everything we need. We also need to confirm that the model is gpt-4.1 or gpt-5, but this is supposed to be a lightweight, quick function to call.
|
||
// Or if we meet the standard threshold for all tool types | ||
return couldTriggerBuiltInGrouping || this._tools.length >= Constant.START_GROUPING_AFTER_TOOL_COUNT; | ||
} | ||
|
||
constructor( | ||
|
@@ -126,19 +133,19 @@ export class ToolGrouping implements IToolGrouping { | |
this._expandOnNext.add(toolName); | ||
} | ||
|
||
async compute(query: string, token: CancellationToken): Promise<LanguageModelToolInformation[]> { | ||
await this._doCompute(query, token); | ||
async compute(query: string, token: CancellationToken, endpoint?: IChatEndpoint): Promise<LanguageModelToolInformation[]> { | ||
await this._doCompute(query, token, endpoint); | ||
return [...this._root.tools()].filter(uniqueFilter(t => t.name)); | ||
} | ||
|
||
async computeAll(query: string, token: CancellationToken): Promise<(LanguageModelToolInformation | VirtualTool)[]> { | ||
await this._doCompute(query, token); | ||
async computeAll(query: string, token: CancellationToken, endpoint?: IChatEndpoint): Promise<(LanguageModelToolInformation | VirtualTool)[]> { | ||
await this._doCompute(query, token, endpoint); | ||
return this._root.contents; | ||
} | ||
|
||
private async _doCompute(query: string, token: CancellationToken) { | ||
private async _doCompute(query: string, token: CancellationToken, endpoint?: IChatEndpoint) { | ||
if (this._didToolsChange) { | ||
await this._grouper.addGroups(query, this._root, this._tools.slice(), token); | ||
await this._grouper.addGroups(query, this._root, this._tools.slice(), token, endpoint); | ||
this._didToolsChange = false; | ||
} | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Comment claims to match VirtualToolGrouper.addGroups logic, but this condition does not check the model family (GPT-only restriction there). This may enable grouping (and related UI/state expectations) for non-GPT models once tool count > threshold, diverging from the actual grouping behavior. Pass endpoint or defer enablement until model family is known, or update the comment and naming to reflect the broader condition.
See below for a potential fix:
Copilot uses AI. Check for mistakes.