Forked from
/**
* AI Toolbox Plugin - Dynamic Tools Provider (v1.5.0 Compatible)
*
* This provider dynamically registers tools based on the current user configuration.
* It respects UI toggles in real-time, preventing crashes when tools are disabled.
*/
import type { Tool, ToolsProviderController } from '@lmstudio/sdk';
import type { PluginConfig } from './config.js';
import { configSchematics } from './config.js';
import { StateManager } from './stateManager.js';
import { BackgroundCommandManager } from './backgroundCommands.js';
// Import tool registration functions (alphabetically sorted)
import { registerBackupTools } from './tools/backupTools.js';
import { registerBackgroundCommandTools } from './tools/backgroundCommandTools.js';
import { registerBrowserTools } from './tools/browserAutomationTools.js';
import { registerCleanupBackupsTool } from './tools/cleanupBackupsTool.js';
import { registerContextManagementTools } from './tools/contextManagementTools.js';
import { registerDataVisualizationTools } from './tools/dataVisualizationTools.js';
import { registerDatabaseTools } from './tools/databaseTools.js';
import { registerDocumentTools } from './tools/documentTools.js';
import { registerExecutionTools } from './tools/executionTools.js';
import { registerFileSystemTools } from './tools/fileSystemTools.js';
import { registerGitTools } from './tools/gitGithubTools.js';
import { registerHttpClientTools } from './tools/httpClientTools.js';
import { registerImageProcessingTools } from './tools/imageProcessingTools.js';
import { registerLineOperationsTools } from './tools/lineOperations.js';
import { registerMarkdownPreviewTools } from './tools/markdownPreviewTools.js';
import { registerRefactorCodeTools } from './tools/refactorCodeTools.js';
import { registerRagTools } from './tools/vectorRagTools.js';
import { registerTextProcessingTools } from './tools/textProcessingTools.js';
import { registerUiGenerationTools } from './tools/uiGenerationTools.js';
import { registerWebResearchTools } from './tools/webResearchTools.js';
let stateManager: StateManager;
let backgroundCommandManager: BackgroundCommandManager;
export async function toolsProvider(ctl: ToolsProviderController): Promise<Tool[]> {
// 1. Get current configuration (respects UI toggles) — use .get() method!
const pluginConfig = ctl.getPluginConfig(configSchematics);
// Construct typed PluginConfig from ParsedConfig .get() calls
const config: PluginConfig = {
fileSystem: pluginConfig.get('fileSystem'),
webSearch: pluginConfig.get('webSearch'),
browserAutomation: pluginConfig.get('browserAutomation'),
gitOperations: pluginConfig.get('gitOperations'),
packageManage: pluginConfig.get('packageManage'),
databaseQueries: pluginConfig.get('databaseQueries'),
documentParsing: pluginConfig.get('documentParsing'),
backgroundCommands: pluginConfig.get('backgroundCommands'),
imageProcessing: pluginConfig.get('imageProcessing'),
httpClient: pluginConfig.get('httpClient'),
vectorRAG: pluginConfig.get('vectorRAG'),
uiGeneration: pluginConfig.get('uiGeneration'),
contextManagement: pluginConfig.get('contextManagement'),
textProcessing: pluginConfig.get('textProcessing'),
refactorCode: pluginConfig.get('refactorCode'),
utility: pluginConfig.get('utility'),
godMode: pluginConfig.get('godMode'),
documentRAG: pluginConfig.get('documentRAG'),
retrievalLimit: pluginConfig.get('retrievalLimit'),
retrievalAffinityThreshold: pluginConfig.get('retrievalAffinityThreshold'),
executionJavaScript: pluginConfig.get('executionJavaScript'),
executionPython: pluginConfig.get('executionPython'),
executionTerminal: pluginConfig.get('executionTerminal'),
executionShell: pluginConfig.get('executionShell'),
executionTests: pluginConfig.get('executionTests'),
searchFallbackChain: pluginConfig.get('searchFallbackChain') as 'ddg-api' | 'ddg-fetch' | 'google' | 'bing',
maxSearchResults: pluginConfig.get('maxSearchResults'),
safesearch: pluginConfig.get('safesearch') as '0' | '1' | '2',
browserTimeout: pluginConfig.get('browserTimeout'),
headlessMode: pluginConfig.get('headlessMode'),
gitAutoCommit: pluginConfig.get('gitAutoCommit'),
defaultBranch: pluginConfig.get('defaultBranch'),
pathValidationEnabled: pluginConfig.get('pathValidationEnabled'),
binaryFileDetection: pluginConfig.get('binaryFileDetection'),
regexReDoSProtection: pluginConfig.get('regexReDoSProtection'),
maxRegexLength: pluginConfig.get('maxRegexLength'),
statePersistenceEnabled: pluginConfig.get('statePersistenceEnabled'),
stateMaxSize: pluginConfig.get('stateMaxSize'),
language: pluginConfig.get('language') as 'en' | 'de' | 'zh-CN' | 'zh-TW',
notificationsEnabled: pluginConfig.get('notificationsEnabled'),
temporalAwareness: pluginConfig.get('temporalAwareness'),
dateFormatStyle: pluginConfig.get('dateFormatStyle') as 'standard' | 'heuteIst',
contextGuardEnabled: pluginConfig.get('contextGuardEnabled'),
contextGuardTokenLimit: pluginConfig.get('contextGuardTokenLimit'),
contextGuardSmartReading: pluginConfig.get('contextGuardSmartReading'),
contextGuardSummaryModel: pluginConfig.get('contextGuardSummaryModel'),
contextGuardTerminalFilterEnabled: pluginConfig.get('contextGuardTerminalFilterEnabled'),
contextGuardTerminalFilterLength: pluginConfig.get('contextGuardTerminalFilterLength'),
autoTrackingEnabled: pluginConfig.get('autoTrackingEnabled'),
autoTrackTokenThreshold: pluginConfig.get('autoTrackTokenThreshold'),
autoTrackDecisions: pluginConfig.get('autoTrackDecisions'),
autoTrackCompletions: pluginConfig.get('autoTrackCompletions'),
autoTrackErrors: pluginConfig.get('autoTrackErrors'),
autoSummaryInterval: pluginConfig.get('autoSummaryInterval'),
maxToolsInSchema: pluginConfig.get('maxToolsInSchema'),
};
// Initialize StateManager if not already done
if (!stateManager) {
stateManager = new StateManager(config);
}
// Initialize BackgroundCommandManager if not already done
if (!backgroundCommandManager) {
backgroundCommandManager = new BackgroundCommandManager(config);
}
// GOD MODE: when enabled, bypass all individual toggles and activate every tool
const isGodMode = config.godMode;
const tools: Tool[] = [];
// --- Background Commands ---
if (config.backgroundCommands || isGodMode) {
tools.push(...registerBackgroundCommandTools(config, backgroundCommandManager));
}
// --- Browser Automation Tools ---
if (config.browserAutomation || isGodMode) {
tools.push(...registerBrowserTools(config));
}
// --- Context Management Tools ---
if (config.contextManagement || isGodMode) {
tools.push(...registerContextManagementTools(config, stateManager));
}
// --- Database Queries ---
if (config.databaseQueries || isGodMode) {
tools.push(...registerDatabaseTools(config));
}
// --- Document Parsing ---
if (config.documentParsing || isGodMode) {
tools.push(...registerDocumentTools(config));
}
// --- Execution Tools (JS/Python/Terminal) — per-tool gating, GOD MODE bypasses all ---
const hasAnyExecToggle = config.executionJavaScript ||
config.executionPython ||
config.executionTerminal ||
config.executionShell ||
config.executionTests;
if (hasAnyExecToggle || isGodMode) {
const allExecTools = registerExecutionTools(config);
// run_javascript — gated by executionJavaScript (or GOD MODE)
if (config.executionJavaScript || isGodMode) {
const jsTool = allExecTools.find(t => t.name === 'run_javascript');
if (jsTool) tools.push(jsTool);
}
// run_python — gated by executionPython (or GOD MODE)
if (config.executionPython || isGodMode) {
const pyTool = allExecTools.find(t => t.name === 'run_python');
if (pyTool) tools.push(pyTool);
}
// run_in_terminal — gated by executionTerminal (or GOD MODE)
if (config.executionTerminal || isGodMode) {
const termTool = allExecTools.find(t => t.name === 'run_in_terminal');
if (termTool) tools.push(termTool);
}
// execute_command — gated by executionShell (or GOD MODE)
if (config.executionShell || isGodMode) {
const shellTool = allExecTools.find(t => t.name === 'execute_command');
if (shellTool) tools.push(shellTool);
}
// run_tests — gated by executionTests (or GOD MODE)
if (config.executionTests || isGodMode) {
const testTool = allExecTools.find(t => t.name === 'run_tests');
if (testTool) tools.push(testTool);
}
}
// --- File System Tools ---
if (config.fileSystem || isGodMode) {
tools.push(...registerFileSystemTools(config, stateManager));
}
// --- Git & GitHub Tools ---
if (config.gitOperations || isGodMode) {
tools.push(...registerGitTools(config));
}
// --- HTTP Client Tools ---
if (config.httpClient || isGodMode) {
tools.push(...registerHttpClientTools(config));
}
// --- Image Processing Tools ---
if (config.imageProcessing || isGodMode) {
tools.push(...registerImageProcessingTools(config));
}
// --- Refactor Code Tools ---
if (config.refactorCode || isGodMode) {
tools.push(...registerRefactorCodeTools(config));
}
// --- Text Processing Tools ---
if (config.textProcessing || isGodMode) {
tools.push(...registerTextProcessingTools(config));
}
// --- UI Generation Tools ---
if (config.uiGeneration || isGodMode) {
tools.push(...registerUiGenerationTools(config));
}
// --- Utility & Maintenance Tools ---
if (config.utility || isGodMode) {
tools.push(...registerBackupTools(config));
tools.push(...registerCleanupBackupsTool(config));
tools.push(...registerDataVisualizationTools(config));
tools.push(...registerLineOperationsTools(config));
tools.push(...registerMarkdownPreviewTools(config));
}
// --- Vector RAG / Semantic Search ---
if (config.vectorRAG || isGodMode) {
tools.push(...registerRagTools(config));
}
// --- Web Research Tools ---
if (config.webSearch || isGodMode) {
tools.push(...registerWebResearchTools(config));
}
// Sort alphabetically by tool name for consistent UI ordering in LM Studio
const sortedTools = [...tools].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
return sortedTools;
}