src / tools / toolsProvider.ts

/**
 * @file toolsProvider.ts
 * Thin orchestrator — composes tools from sub-modules.
 */

import type { Tool, ToolsProvider } from "@lmstudio/sdk";
import { toolsPluginConfig } from "./config";
import { getPersistedState, savePersistedState, ensureWorkspaceExists } from "./stateManager";
import type { ToolContext } from "./shared";
import { createGitTools } from "./gitTools";
import { createFileTools } from "./fileTools";
import { createCodeTools } from "./codeTools";
import { createWebTools } from "./webTools";
import { createSystemTools } from "./systemTools";
import { createSecondaryAgentTool } from "./secondaryAgent";

export const toolsProvider: ToolsProvider = async (ctl) => {
  const pluginConfig = ctl.getPluginConfig(toolsPluginConfig);

  // Load state
  const fullState = await getPersistedState();
  const configCwd = pluginConfig.get("defaultWorkingDirectory");

  // Shared mutable context — all modules see cwd changes
  const ctx: ToolContext = {
    cwd: configCwd || fullState.currentWorkingDirectory,
    fullState,
    saveState: () => savePersistedState(fullState),
  };

  // Config flags
  const allowAllCode = pluginConfig.get("allowAllCode");
  const allowJavascript = allowAllCode || pluginConfig.get("allowJavascriptExecution");
  const allowPython = allowAllCode || pluginConfig.get("allowPythonExecution");
  const allowTerminal = allowAllCode || pluginConfig.get("allowTerminalExecution");
  const allowShell = allowAllCode || pluginConfig.get("allowShellCommandExecution");
  const allowGit = pluginConfig.get("allowGitOperations");
  const allowDb = pluginConfig.get("allowDatabaseInspection");
  const allowNotify = pluginConfig.get("allowSystemNotifications");
  const enableWikipedia = pluginConfig.get("enableWikipediaTool");
  const enableSecondary = pluginConfig.get("enableSecondaryAgent");

  // Ensure workspace exists (no-op if already exists, safe to call every time)
  await ensureWorkspaceExists(ctx.cwd);

  // Compose tools from modules
  const tools: Tool[] = [];

  if (allowGit) tools.push(...createGitTools(ctx));

  tools.push(...createFileTools(ctx));

  const codeResult = createCodeTools(ctx, {
    allowJavascript, allowPython, allowShell, allowTerminal,
  });
  tools.push(...codeResult.tools);

  tools.push(...createWebTools({ enableWikipedia }));

  tools.push(...createSystemTools(ctx, { allowNotify, allowDb }));

  if (enableSecondary) {
    tools.push(createSecondaryAgentTool(ctx, {
      pluginConfig,
      originalRunJavascript: codeResult.originalRunJavascript,
      originalRunPython: codeResult.originalRunPython,
    }));
  }

  return tools;
};