Skip to content

Conversation

bryanchen-d
Copy link
Contributor

Pass model info into the alternativeDefinition method of ICopilotTool to allow tools to provide alternative definition based on different models passing in.

@Copilot Copilot AI review requested due to automatic review settings October 17, 2025 17:05
@bryanchen-d bryanchen-d self-assigned this Oct 17, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds model-aware alternativeDefinition support so tools can provide different LanguageModelToolInformation depending on the selected model.

  • Extends ICopilotTool.alternativeDefinition to accept the current model.
  • Applies alternativeDefinition in three getEnabledTools implementations before filtering.
  • Updates interface documentation to mention model-based customization.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
test/base/extHostContext/simulationExtHostToolsService.ts Adds model-aware mapping to substitute tool definitions before filtering.
src/extension/tools/vscode-node/toolsService.ts Introduces model-based alternativeDefinition application prior to existing enable/disable logic.
src/extension/tools/node/test/testToolsService.ts Mirrors production logic for model-driven alternativeDefinition in test service.
src/extension/tools/common/toolsRegistry.ts Updates ICopilotTool interface and docs to accept model info in alternativeDefinition.

Comment on lines 125 to 137
return this.tools
.map(tool => {
// Apply model-specific alternative if available via alternativeDefinition
const owned = this.copilotTools.get(getToolName(tool.name) as ToolName);
if (owned?.alternativeDefinition) {
const alternative = owned.alternativeDefinition(request.model);
if (alternative) {
return alternative;
}
}
return tool;
})
.filter(tool => filter?.(tool) ?? (!this._disabledTools.has(getToolName(tool.name)) && packageJsonTools.has(tool.name)));
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The model-specific alternativeDefinition mapping logic is duplicated in three services; extracting a shared helper (e.g., applyAlternativeToolDefinition(tools, request, lookupFn)) would reduce repetition and risk of divergence if the logic changes.

Copilot uses AI. Check for mistakes.

Comment on lines 146 to 158
return this.tools
.map(tool => {
// Apply model-specific alternative if available via alternativeDefinition
const owned = this._copilotTools.get(getToolName(tool.name) as ToolName);
if (owned?.value?.alternativeDefinition) {
const alternative = owned.value.alternativeDefinition(request.model);
if (alternative) {
return alternative;
}
}
return tool;
})
.filter(tool => {
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This mapping block repeats the same alternativeDefinition substitution pattern found in other services; consider consolidating into a reusable utility to minimize duplicated logic and simplify future changes.

Copilot uses AI. Check for mistakes.

Comment on lines 52 to 60
* can be driven by EXP for example, or customized based on the current model.
* ⚠️ A tool using an alternative definition MUST still accept its default
* parameters because the alternative definition will only be applied within
* the Copilot extension, not other extensions' usages via `vscode.lm.tools`.
*
* @param modelInfo Optional information about the currently selected language model.
* If provided, allows customizing the tool definition per model.
*/
alternativeDefinition?(): vscode.LanguageModelToolInformation | undefined;
alternativeDefinition?(modelInfo?: vscode.LanguageModelChat): vscode.LanguageModelToolInformation | undefined;
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The documentation specifies parameter acceptance but does not clarify expectations about immutable fields (e.g., tool name); if name or signature changes are disallowed, explicitly stating that the alternativeDefinition must preserve the original tool's name and parameter schema would prevent misuse.

Copilot uses AI. Check for mistakes.

@vs-code-engineering vs-code-engineering bot added this to the October 2025 milestone Oct 17, 2025
// Apply model-specific alternative if available via alternativeDefinition
const owned = this._copilotTools.value.get(getToolName(tool.name) as ToolName);
if (owned?.alternativeDefinition) {
const alternative = owned.alternativeDefinition(endpoint);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We call alternativeDefinition in the tools getter, would it make sense to change that to be model-specific? Like getTools(model)? Or should it stay generic and we only apply the model-specific stuff here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, feels like tools consumers should all call getEnabledTools, then it is better the tools getter stay generic - also consider there is a cache - I wonder if we should not call alternativeDefinition in the tools getter as we will call it later in getEnabledTools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants