如何在VS Code扩展中动态注册Language Model Tools?
动态注册VS Code Language Model Tools的可行性说明
目前VS Code的Copilot工具系统要求必须在package.json中静态声明工具,才能让工具出现在Copilot的工具列表里。仅通过vscode.lm.registerTool(...)在运行时注册的工具,无法被Copilot的静态扫描机制捕获,因此不会显示在工具列表中。
背后的原因
VS Code的Copilot工具发现流程依赖于扩展激活前对package.json中contributes.lmTools字段的静态扫描,它会基于这个字段预先生成工具列表。运行时动态注册的工具不会被这个扫描流程识别,自然无法出现在Copilot的可选工具中。
折中实现动态控制的方案
虽然不能完全动态添加未在package.json声明的工具,但可以通过以下方式实现基于配置动态控制工具是否可用:
1. 提前声明所有潜在工具
先在package.json中列出所有可能用到的工具,然后在扩展代码中根据配置决定是否实际实现这些工具的逻辑:
// package.json "contributes": { "lmTools": [ { "id": "myExtension.toolA", "label": "工具A", "description": "执行功能A" }, { "id": "myExtension.toolB", "label": "工具B", "description": "执行功能B" } ] }
2. 基于配置动态注册工具逻辑
在扩展激活时读取配置,仅为需要启用的工具注册实际执行逻辑,未启用的工具可以注册空实现(避免调用报错):
import * as vscode from 'vscode'; let toolDisposables: vscode.Disposable[] = []; // 根据配置注册/注销工具 function syncToolsWithConfig() { // 清理之前的注册 toolDisposables.forEach(d => d.dispose()); toolDisposables = []; const config = vscode.workspace.getConfiguration('myExtension'); const enableToolA = config.get<boolean>('enableToolA', false); const enableToolB = config.get<boolean>('enableToolB', false); if (enableToolA) { const disposable = vscode.lm.registerTool({ id: 'myExtension.toolA', execute: async (args) => { // 工具A的实际业务逻辑 return { content: `工具A执行完成,参数:${JSON.stringify(args)}` }; } }); toolDisposables.push(disposable); } else { // 未启用时注册空实现,提示用户配置 const disposable = vscode.lm.registerTool({ id: 'myExtension.toolA', execute: async () => { return { content: '请在扩展配置中启用工具A' }; } }); toolDisposables.push(disposable); } if (enableToolB) { const disposable = vscode.lm.registerTool({ id: 'myExtension.toolB', execute: async (args) => { // 工具B的实际业务逻辑 return { content: `工具B执行完成,参数:${JSON.stringify(args)}` }; } }); toolDisposables.push(disposable); } } export function activate(context: vscode.ExtensionContext) { // 初始注册工具 syncToolsWithConfig(); // 监听配置变更,实时同步工具状态 const configListener = vscode.workspace.onDidChangeConfiguration(e => { if (e.affectsConfiguration('myExtension.enableToolA') || e.affectsConfiguration('myExtension.enableToolB')) { syncToolsWithConfig(); } }); context.subscriptions.push(configListener); }
方案优缺点
- 优点:能实现基于配置动态控制工具的可用性,用户在Copilot列表中能看到所有声明的工具,仅启用的工具可正常执行。
- 缺点:所有可能用到的工具必须提前在
package.json中声明,无法完全动态添加全新的工具(比如从远程拉取的工具定义)。
内容的提问来源于stack exchange,提问作者leonard520
相关产品推荐
相关产品推荐

