mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-15 07:28:05 +00:00
tools: remove tool limit warning (#290581)
Virtual tools are pretty good now, and with the upcoming tool search tool for Anthropic models it no longer makes sense to maintain a warning about them. - Remove 'too many tools enabled' warning indicator from configure tools action - Remove tool limit validation message from tool picker - Remove chatToolCount context key - Remove chatToolGroupingThreshold context key - Remove autorun that tracked enabled tool count in chat input (Commit message generated by Copilot)
This commit is contained in:
2
.vscode/notebooks/my-work.github-issues
vendored
2
.vscode/notebooks/my-work.github-issues
vendored
@@ -7,7 +7,7 @@
|
||||
{
|
||||
"kind": 2,
|
||||
"language": "github-issues",
|
||||
"value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce repo:microsoft/vscode-copilot-issues repo:microsoft/vscode-extension-samples\n\n// current milestone name\n$MILESTONE=milestone:\"December 2025\"\n"
|
||||
"value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce repo:microsoft/vscode-copilot-issues repo:microsoft/vscode-extension-samples\n\n// current milestone name\n$MILESTONE=milestone:\"January 2026\"\n"
|
||||
},
|
||||
{
|
||||
"kind": 1,
|
||||
|
||||
@@ -3,24 +3,18 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { $ } from '../../../../../base/browser/dom.js';
|
||||
import { CancellationTokenSource } from '../../../../../base/common/cancellation.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { Iterable } from '../../../../../base/common/iterator.js';
|
||||
import { KeyCode, KeyMod } from '../../../../../base/common/keyCodes.js';
|
||||
import { markAsSingleton } from '../../../../../base/common/lifecycle.js';
|
||||
import { autorun } from '../../../../../base/common/observable.js';
|
||||
import { ThemeIcon } from '../../../../../base/common/themables.js';
|
||||
import { ServicesAccessor } from '../../../../../editor/browser/editorExtensions.js';
|
||||
import { localize, localize2 } from '../../../../../nls.js';
|
||||
import { IActionViewItemService } from '../../../../../platform/actions/browser/actionViewItemService.js';
|
||||
import { MenuEntryActionViewItem } from '../../../../../platform/actions/browser/menuEntryActionViewItem.js';
|
||||
import { Action2, MenuId, MenuItemAction, registerAction2 } from '../../../../../platform/actions/common/actions.js';
|
||||
import { Action2, MenuId, registerAction2 } from '../../../../../platform/actions/common/actions.js';
|
||||
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
|
||||
import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';
|
||||
import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../../common/contributions.js';
|
||||
import { ChatContextKeys } from '../../common/actions/chatContextKeys.js';
|
||||
import { ConfirmedReason, IChatToolInvocation, ToolConfirmKind } from '../../common/chatService/chatService.js';
|
||||
import { isResponseVM } from '../../common/model/chatViewModel.js';
|
||||
@@ -234,80 +228,8 @@ class ConfigureToolsAction extends Action2 {
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigureToolsActionRendering implements IWorkbenchContribution {
|
||||
|
||||
static readonly ID = 'chat.configureToolsActionRendering';
|
||||
|
||||
constructor(
|
||||
@IActionViewItemService actionViewItemService: IActionViewItemService,
|
||||
) {
|
||||
const disposable = actionViewItemService.register(MenuId.ChatInput, ConfigureToolsAction.ID, (action, _opts, instantiationService) => {
|
||||
if (!(action instanceof MenuItemAction)) {
|
||||
return undefined;
|
||||
}
|
||||
return instantiationService.createInstance(class extends MenuEntryActionViewItem {
|
||||
private warningElement!: HTMLElement;
|
||||
|
||||
override render(container: HTMLElement): void {
|
||||
super.render(container);
|
||||
|
||||
// Add warning indicator element
|
||||
this.warningElement = $(`.tool-warning-indicator${ThemeIcon.asCSSSelector(Codicon.warning)}`);
|
||||
this.warningElement.style.display = 'none';
|
||||
container.appendChild(this.warningElement);
|
||||
container.style.position = 'relative';
|
||||
|
||||
// Set up context key listeners
|
||||
this.updateWarningState();
|
||||
this._register(this._contextKeyService.onDidChangeContext(() => {
|
||||
this.updateWarningState();
|
||||
}));
|
||||
}
|
||||
|
||||
private updateWarningState(): void {
|
||||
const wasShown = this.warningElement.style.display === 'block';
|
||||
const shouldBeShown = this.isAboveToolLimit();
|
||||
|
||||
if (!wasShown && shouldBeShown) {
|
||||
this.warningElement.style.display = 'block';
|
||||
this.updateTooltip();
|
||||
} else if (wasShown && !shouldBeShown) {
|
||||
this.warningElement.style.display = 'none';
|
||||
this.updateTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
protected override getTooltip(): string {
|
||||
if (this.isAboveToolLimit()) {
|
||||
const warningMessage = localize('chatTools.tooManyEnabled', 'More than {0} tools are enabled, you may experience degraded tool calling.', this._contextKeyService.getContextKeyValue(ChatContextKeys.chatToolGroupingThreshold.key));
|
||||
return `${warningMessage}`;
|
||||
}
|
||||
|
||||
return super.getTooltip();
|
||||
}
|
||||
|
||||
private isAboveToolLimit() {
|
||||
const rawToolLimit = this._contextKeyService.getContextKeyValue(ChatContextKeys.chatToolGroupingThreshold.key);
|
||||
const rawToolCount = this._contextKeyService.getContextKeyValue(ChatContextKeys.chatToolCount.key);
|
||||
if (rawToolLimit === undefined || rawToolCount === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const toolLimit = Number(rawToolLimit || 0);
|
||||
const toolCount = Number(rawToolCount || 0);
|
||||
return toolCount > toolLimit;
|
||||
}
|
||||
}, action, undefined);
|
||||
});
|
||||
|
||||
// Reduces flicker a bit on reload/restart
|
||||
markAsSingleton(disposable);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerChatToolActions() {
|
||||
registerAction2(AcceptToolConfirmation);
|
||||
registerAction2(SkipToolConfirmation);
|
||||
registerAction2(ConfigureToolsAction);
|
||||
registerWorkbenchContribution2(ConfigureToolsActionRendering.ID, ConfigureToolsActionRendering, WorkbenchPhase.BlockRestore);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,11 @@ import { assertNever } from '../../../../../base/common/assert.js';
|
||||
import { CancellationToken } from '../../../../../base/common/cancellation.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { Emitter, Event } from '../../../../../base/common/event.js';
|
||||
import { createMarkdownCommandLink } from '../../../../../base/common/htmlContent.js';
|
||||
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
|
||||
import Severity from '../../../../../base/common/severity.js';
|
||||
import { ThemeIcon } from '../../../../../base/common/themables.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { CommandsRegistry, ICommandService } from '../../../../../platform/commands/common/commands.js';
|
||||
import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
|
||||
import { ExtensionIdentifier } from '../../../../../platform/extensions/common/extensions.js';
|
||||
import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickTreeItem } from '../../../../../platform/quickinput/common/quickInput.js';
|
||||
@@ -24,7 +21,6 @@ import { McpCommandIds } from '../../../mcp/common/mcpCommandIds.js';
|
||||
import { IMcpRegistry } from '../../../mcp/common/mcpRegistryTypes.js';
|
||||
import { IMcpServer, IMcpService, IMcpWorkbenchService, McpConnectionState, McpServerCacheState, McpServerEditorTab } from '../../../mcp/common/mcpTypes.js';
|
||||
import { startServerAndWaitForLiveTools } from '../../../mcp/common/mcpTypesUtils.js';
|
||||
import { ChatContextKeys } from '../../common/actions/chatContextKeys.js';
|
||||
import { ILanguageModelChatMetadata } from '../../common/languageModels.js';
|
||||
import { ILanguageModelToolsService, IToolData, IToolSet, ToolDataSource, ToolSet } from '../../common/tools/languageModelToolsService.js';
|
||||
import { ConfigureToolSets } from '../tools/toolSetsContribution.js';
|
||||
@@ -210,7 +206,6 @@ export async function showToolsPicker(
|
||||
const mcpWorkbenchService = accessor.get(IMcpWorkbenchService);
|
||||
const toolsService = accessor.get(ILanguageModelToolsService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
const toolLimit = accessor.get(IContextKeyService).getContextKeyValue<number>(ChatContextKeys.chatToolGroupingThreshold.key);
|
||||
|
||||
const mcpServerByTool = new Map<string, IMcpServer>();
|
||||
for (const server of mcpService.servers.get()) {
|
||||
@@ -484,32 +479,6 @@ export async function showToolsPicker(
|
||||
}
|
||||
}));
|
||||
|
||||
const updateToolLimitMessage = () => {
|
||||
if (toolLimit) {
|
||||
let count = 0;
|
||||
const traverse = (items: readonly AnyTreeItem[]) => {
|
||||
for (const item of items) {
|
||||
if (isBucketTreeItem(item) || isToolSetTreeItem(item)) {
|
||||
if (item.children) {
|
||||
traverse(item.children);
|
||||
}
|
||||
} else if (isToolTreeItem(item) && item.checked) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
};
|
||||
traverse(treePicker.itemTree);
|
||||
if (count > toolLimit) {
|
||||
treePicker.severity = Severity.Warning;
|
||||
treePicker.validationMessage = localize('toolLimitExceeded', "{0} tools are enabled. You may experience degraded tool calling above {1} tools.", count, createMarkdownCommandLink({ title: String(toolLimit), id: '_chat.toolPicker.closeAndOpenVirtualThreshold' }));
|
||||
} else {
|
||||
treePicker.severity = Severity.Ignore;
|
||||
treePicker.validationMessage = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
updateToolLimitMessage();
|
||||
|
||||
const collectResults = () => {
|
||||
|
||||
const result = new Map<IToolData | IToolSet, boolean>();
|
||||
@@ -537,18 +506,6 @@ export async function showToolsPicker(
|
||||
return result;
|
||||
};
|
||||
|
||||
// Temporary command to close the picker and open settings, for use in the validation message
|
||||
store.add(CommandsRegistry.registerCommand({
|
||||
id: '_chat.toolPicker.closeAndOpenVirtualThreshold',
|
||||
handler: () => {
|
||||
treePicker.hide();
|
||||
commandService.executeCommand('workbench.action.openSettings', 'github.copilot.chat.virtualTools.threshold');
|
||||
}
|
||||
}));
|
||||
|
||||
// Handle checkbox state changes
|
||||
store.add(treePicker.onDidChangeCheckedLeafItems(() => updateToolLimitMessage()));
|
||||
|
||||
// Handle acceptance
|
||||
let didAccept = false;
|
||||
const didAcceptFinalItem = store.add(new Emitter<void>());
|
||||
|
||||
@@ -535,20 +535,6 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
||||
}
|
||||
this.chatSessionHasCustomAgentTarget = ChatContextKeys.chatSessionHasCustomAgentTarget.bindTo(contextKeyService);
|
||||
|
||||
const chatToolCount = ChatContextKeys.chatToolCount.bindTo(contextKeyService);
|
||||
|
||||
this._register(autorun(reader => {
|
||||
let count = 0;
|
||||
const userSelectedTools = this.selectedToolsModel.userSelectedTools.read(reader);
|
||||
for (const key in userSelectedTools) {
|
||||
if (userSelectedTools[key] === true) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
chatToolCount.set(count);
|
||||
}));
|
||||
|
||||
this.history = this._register(this.instantiationService.createInstance(ChatHistoryNavigator, this.location));
|
||||
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
|
||||
@@ -35,8 +35,6 @@ export namespace ChatContextKeys {
|
||||
export const inChatEditor = new RawContextKey<boolean>('inChatEditor', false, { type: 'boolean', description: localize('inChatEditor', "Whether focus is in a chat editor.") });
|
||||
export const inChatTerminalToolOutput = new RawContextKey<boolean>('inChatTerminalToolOutput', false, { type: 'boolean', description: localize('inChatTerminalToolOutput', "True when focus is in the chat terminal output region.") });
|
||||
export const chatModeKind = new RawContextKey<ChatModeKind>('chatAgentKind', ChatModeKind.Ask, { type: 'string', description: localize('agentKind', "The 'kind' of the current agent.") });
|
||||
export const chatToolCount = new RawContextKey<number>('chatToolCount', 0, { type: 'number', description: localize('chatToolCount', "The number of tools available in the current agent.") });
|
||||
export const chatToolGroupingThreshold = new RawContextKey<number>('chat.toolGroupingThreshold', 0, { type: 'number', description: localize('chatToolGroupingThreshold', "The number of tools at which we start doing virtual grouping.") });
|
||||
|
||||
export const supported = ContextKeyExpr.or(IsWebContext.negate(), RemoteNameContext.notEqualsTo(''), ContextKeyExpr.has('config.chat.experimental.serverlessWebEnabled'));
|
||||
export const enabled = new RawContextKey<boolean>('chatIsEnabled', false, { type: 'boolean', description: localize('chatIsEnabled', "True when chat is enabled because a default chat participant is activated with an implementation.") });
|
||||
|
||||
Reference in New Issue
Block a user