src / config.ts
src / config.ts
import { createConfigSchematics } from "@lmstudio/sdk";
import { getSystemDict } from "./locales/i18n";
const { dict: t, resolvedLocale } = getSystemDict();
const c = t.config;
export const pluginConfigSchematics = createConfigSchematics()
.field("general.planMode", "string", {
displayName: c.planMode.displayName,
subtitle: c.planMode.subtitle,
}, "when_useful")
.field("general.defaultWorkspacePath", "string", {
displayName: "Default Workspace Path",
subtitle:
"Leave empty = LM Studio per-chat working directory. " +
"Set a path to override. Absolute change_directory mid-chat still hot-swaps workspace. " +
"Supports %USERPROFILE%, $HOME, ~.",
}, "")
.field("execution.sandboxWorkspace", "boolean", {
displayName: "Sandbox Execution to Workspace",
subtitle:
"ON: execute_command / run_python / run_javascript run inside the per-chat working directory " +
"(or your Default Workspace Path) and relative paths resolve there. OFF: no directory enforcement " +
"(tools use the default process directory). Note: this pins the starting directory; a shell command " +
"can still reference absolute paths.",
}, true)
.field("documentParser.enabled", "boolean", { displayName: "Enable Document Parsing Tools", subtitle: "" }, true)
.field("documentParser.maxFileSizeMB", "numeric", { int: true, min: 1, max: 500, displayName: "Max File Size (MB)", subtitle: "" }, 50)
.field("memory.enabled", "boolean", { displayName: "Enable Long-Term Memory", subtitle: "" }, true)
.field("memory.hotThreshold", "numeric", {
int: true,
min: 10,
max: 100,
displayName: "Hot Memory Threshold",
subtitle: "Number of entries before cold storage compression activates",
}, 30)
.field("memory.neo4jSyncEnabled", "boolean", {
displayName: "Enable Neo4j Memory Sync",
subtitle: "Auto-sync memory to Neo4j for redundancy and graph queries",
}, true)
.field("workflow.max_steps", "numeric", { int: true, min: 1, max: 50, displayName: "Max Workflow Steps", subtitle: "" }, 10)
.field("eval.enabled", "boolean", { displayName: "Enable Agent Evaluation", subtitle: "" }, false)
.field("execution.allowJavascriptExecution", "boolean", {
displayName: "Allow JavaScript Execution",
subtitle: "Run JS via Deno sandbox",
}, false)
.field("execution.allowPythonExecution", "boolean", {
displayName: "Allow Python Execution",
subtitle: "Run Python scripts",
}, false)
.field("execution.allowTerminalExecution", "boolean", {
displayName: "Allow Terminal Execution",
subtitle: "Open interactive terminal windows",
}, false)
.field("execution.allowShellCommandExecution", "boolean", {
displayName: "Allow Shell Commands",
subtitle: "Required for execute_command. When off, that tool returns a clear enable-permission error.",
}, false)
.field("execution.allowBrowserControl", "boolean", {
displayName: "Allow Browser Control",
subtitle: "Puppeteer browser automation",
}, false)
.field("execution.allowAllCode", "boolean", {
displayName: "Allow All Code Execution (Master Switch)",
subtitle: "Enable all execution permissions at once",
}, false)
.field("general.unrestrictedMode", "boolean", {
displayName: "⚠️ UNRESTRICTED MODE (Master Switch — All Tools, No Sandbox)",
subtitle:
"ON: enables EVERY gated tool (shell, python, JS, terminal, browser, git, github, DB, memory, wiki, RAG, secondary agent) " +
"AND disables all workspace path sandboxing — list_directory / read / write / change_directory work on ANY absolute path " +
"on ANY drive (including outside the workspace). OFF: normal per-permission gating. " +
"Only enable for trusted local use — the model can read/write/delete anywhere your user account can.",
}, false)
.field("execution.allowSystemNotifications", "boolean", {
displayName: "Allow System Notifications",
subtitle: "Send desktop notifications via node-notifier",
}, true)
.field("git.allowGitOperations", "boolean", {
displayName: "Enable Git Operations",
subtitle: "git_status, git_diff, git_commit, etc.",
}, true)
.field("git.allowGitHubTools", "boolean", {
displayName: "Enable GitHub CLI Tools",
subtitle: "gh_auth, gh_create_issue, gh_push, etc.",
}, true)
.field("git.allowDatabaseInspection", "boolean", {
displayName: "Enable Database Inspection",
subtitle: "Allow read-only queries on SQLite databases",
}, false)
.field("agent.enableSecondaryAgent", "boolean", {
displayName: "Enable Secondary Agent",
subtitle: "Expose consult_secondary_agent / agent_run_with_retry tools",
}, true)
.field("agent.useMainModelForSubAgent", "boolean", {
displayName: "Use Main Model for Sub-Agent",
subtitle: "Use the currently loaded LM Studio model",
}, true)
.field("agent.secondaryAgentEndpoint", "string", {
displayName: "Secondary Agent Endpoint",
subtitle: "HTTP endpoint for sub-agent API (e.g., http://localhost:1234/v1)",
}, "http://localhost:1234/v1")
.field("agent.secondaryModelId", "string", {
displayName: "Sub-Agent Model ID",
subtitle: "Leave empty to use the currently loaded LM Studio model.",
}, "")
.field("agent.subAgentProfiles", "string", {
displayName: "Sub-Agent Profiles (JSON)",
subtitle: 'Custom prompts for roles like "coder", "reviewer"',
}, '{"summarizer": "You are a summarization expert.", "coder": "You are a software engineer."}')
.field("agent.subAgentFrequency", "string", {
displayName: "Sub-Agent Frequency (reserved)",
subtitle: "No longer auto-injects hints into chat. Sub-agent runs only when you ask or the model calls the tool.",
}, "never")
.field("agent.subAgentAllowFileSystem", "boolean", {
displayName: "Sub-Agent: Allow File System",
subtitle: "Let sub-agent read/write files",
}, true)
.field("agent.subAgentAllowWeb", "boolean", {
displayName: "Sub-Agent: Allow Web Search",
subtitle: "Let sub-agent search the web",
}, true)
.field("agent.subAgentAllowCode", "boolean", {
displayName: "Sub-Agent: Allow Code Execution",
subtitle: "Let sub-agent run code",
}, false)
.field("agent.subAgentAllowBrowserControl", "boolean", {
displayName: "Sub-Agent: Allow Browser Control",
subtitle: "Let sub-agent control browsers",
}, false)
.field("agent.subAgentTimeLimit", "numeric", {
int: true,
min: 30,
max: 3600,
displayName: "Sub-Agent Time Limit (sec)",
subtitle: "Maximum time for a single sub-agent task",
}, 600)
.field("wikipedia.enabled", "boolean", { displayName: "Enable Wikipedia Tool", subtitle: "" }, true)
.field("localRag.enabled", "boolean", { displayName: "Enable Local RAG", subtitle: "" }, false)
.field("retrieval.limit", "numeric", {
int: true,
min: 1,
max: 50,
displayName: "Retrieval Limit",
subtitle: "Maximum number of chunks to retrieve for RAG",
}, 5)
.field("retrieval.threshold", "numeric", {
min: 0.0,
max: 1.0,
step: 0.01,
displayName: "Retrieval Affinity Threshold",
subtitle: "Minimum cosine similarity score for a chunk to be returned",
}, 0.5)
.field("retrieval.embeddingModel", "string", {
displayName: "Embedding Model ID",
subtitle: "LM Studio model ID used for RAG embeddings and semantic memory",
}, "nomic-ai/nomic-embed-text-v1.5-GGUF")
.field("neo4j.uri", "string", {
displayName: "Neo4j URI",
subtitle: "Database connection string (e.g., neo4j://localhost:7687). Scheme is preserved.",
}, "")
.field("neo4j.username", "string", {
displayName: "Neo4j Username",
subtitle: "Default: neo4j",
}, "neo4j")
.field("neo4j.password", "string", {
displayName: "Neo4j Password (sensitive)",
subtitle: "Required for Neo4j tools and memory sync. Stored as plain text in settings.",
}, "")
.field("media.sharpWebpSupport", "boolean", {
displayName: "Enable WebP Support",
subtitle: "Allow WebP image format conversion",
}, true)
.field("media.ffmpegPath", "string", {
displayName: "FFmpeg Path (optional)",
subtitle: "Auto-detected if empty. Required for video/audio tools.",
}, "")
.field("archive.maxArchiveSizeMB", "numeric", {
int: true,
min: 100,
max: 5000,
displayName: "Max Archive Size (MB)",
subtitle: "Maximum allowed archive file size in megabytes",
}, 1024)
.field("automation.cronStoragePath", "string", {
displayName: "Cron Jobs Storage Path",
subtitle: "JSON file for persisting scheduled cron jobs",
}, "")
.field("automation.timeLogStoragePath", "string", {
displayName: "Time Log Storage Path",
subtitle: "File to store time tracking entries",
}, "")
.field("debug.enableDebugMode", "boolean", {
displayName: "Enable Debug Mode (Auto-Debug)",
subtitle: "Automatically review sub-agent code for bugs",
}, false)
.field("debug.enableSubAgentDebugLogging", "boolean", {
displayName: "Enable Sub-Agent Debug Logging",
subtitle: "Detailed logs for troubleshooting sub-agents",
}, false)
.field("debug.subAgentAutoSave", "boolean", {
displayName: "Sub-Agent Auto-Save",
subtitle: "Automatically save files generated by sub-agents",
}, true)
.field("debug.showFullCodeOutput", "boolean", {
displayName: "Show Full Code Output",
subtitle: "Display full code in chat (files are still saved)",
}, false)
.field("debug.simpleSystemPrompt", "boolean", {
displayName: "Simple System Prompt",
subtitle: "Use a simplified system prompt to save context window",
}, false)
.field("general.messageLanguage", "string", { displayName: "Message Language", subtitle: "Language for tool responses and status messages" }, resolvedLocale)
.field("general.uiLanguageOverride", "string", { displayName: "UI Language Override", subtitle: "Force UI language (default: auto)" }, "auto")
.build();
import { createConfigSchematics } from "@lmstudio/sdk";
import { getSystemDict } from "./locales/i18n";
const { dict: t, resolvedLocale } = getSystemDict();
const c = t.config;
export const pluginConfigSchematics = createConfigSchematics()
.field("general.planMode", "string", {
displayName: c.planMode.displayName,
subtitle: c.planMode.subtitle,
}, "when_useful")
.field("general.defaultWorkspacePath", "string", {
displayName: "Default Workspace Path",
subtitle:
"Leave empty = LM Studio per-chat working directory. " +
"Set a path to override. Absolute change_directory mid-chat still hot-swaps workspace. " +
"Supports %USERPROFILE%, $HOME, ~.",
}, "")
.field("execution.sandboxWorkspace", "boolean", {
displayName: "Sandbox Execution to Workspace",
subtitle:
"ON: execute_command / run_python / run_javascript run inside the per-chat working directory " +
"(or your Default Workspace Path) and relative paths resolve there. OFF: no directory enforcement " +
"(tools use the default process directory). Note: this pins the starting directory; a shell command " +
"can still reference absolute paths.",
}, true)
.field("documentParser.enabled", "boolean", { displayName: "Enable Document Parsing Tools", subtitle: "" }, true)
.field("documentParser.maxFileSizeMB", "numeric", { int: true, min: 1, max: 500, displayName: "Max File Size (MB)", subtitle: "" }, 50)
.field("memory.enabled", "boolean", { displayName: "Enable Long-Term Memory", subtitle: "" }, true)
.field("memory.hotThreshold", "numeric", {
int: true,
min: 10,
max: 100,
displayName: "Hot Memory Threshold",
subtitle: "Number of entries before cold storage compression activates",
}, 30)
.field("memory.neo4jSyncEnabled", "boolean", {
displayName: "Enable Neo4j Memory Sync",
subtitle: "Auto-sync memory to Neo4j for redundancy and graph queries",
}, true)
.field("workflow.max_steps", "numeric", { int: true, min: 1, max: 50, displayName: "Max Workflow Steps", subtitle: "" }, 10)
.field("eval.enabled", "boolean", { displayName: "Enable Agent Evaluation", subtitle: "" }, false)
.field("execution.allowJavascriptExecution", "boolean", {
displayName: "Allow JavaScript Execution",
subtitle: "Run JS via Deno sandbox",
}, false)
.field("execution.allowPythonExecution", "boolean", {
displayName: "Allow Python Execution",
subtitle: "Run Python scripts",
}, false)
.field("execution.allowTerminalExecution", "boolean", {
displayName: "Allow Terminal Execution",
subtitle: "Open interactive terminal windows",
}, false)
.field("execution.allowShellCommandExecution", "boolean", {
displayName: "Allow Shell Commands",
subtitle: "Required for execute_command. When off, that tool returns a clear enable-permission error.",
}, false)
.field("execution.allowBrowserControl", "boolean", {
displayName: "Allow Browser Control",
subtitle: "Puppeteer browser automation",
}, false)
.field("execution.allowAllCode", "boolean", {
displayName: "Allow All Code Execution (Master Switch)",
subtitle: "Enable all execution permissions at once",
}, false)
.field("general.unrestrictedMode", "boolean", {
displayName: "⚠️ UNRESTRICTED MODE (Master Switch — All Tools, No Sandbox)",
subtitle:
"ON: enables EVERY gated tool (shell, python, JS, terminal, browser, git, github, DB, memory, wiki, RAG, secondary agent) " +
"AND disables all workspace path sandboxing — list_directory / read / write / change_directory work on ANY absolute path " +
"on ANY drive (including outside the workspace). OFF: normal per-permission gating. " +
"Only enable for trusted local use — the model can read/write/delete anywhere your user account can.",
}, false)
.field("execution.allowSystemNotifications", "boolean", {
displayName: "Allow System Notifications",
subtitle: "Send desktop notifications via node-notifier",
}, true)
.field("git.allowGitOperations", "boolean", {
displayName: "Enable Git Operations",
subtitle: "git_status, git_diff, git_commit, etc.",
}, true)
.field("git.allowGitHubTools", "boolean", {
displayName: "Enable GitHub CLI Tools",
subtitle: "gh_auth, gh_create_issue, gh_push, etc.",
}, true)
.field("git.allowDatabaseInspection", "boolean", {
displayName: "Enable Database Inspection",
subtitle: "Allow read-only queries on SQLite databases",
}, false)
.field("agent.enableSecondaryAgent", "boolean", {
displayName: "Enable Secondary Agent",
subtitle: "Expose consult_secondary_agent / agent_run_with_retry tools",
}, true)
.field("agent.useMainModelForSubAgent", "boolean", {
displayName: "Use Main Model for Sub-Agent",
subtitle: "Use the currently loaded LM Studio model",
}, true)
.field("agent.secondaryAgentEndpoint", "string", {
displayName: "Secondary Agent Endpoint",
subtitle: "HTTP endpoint for sub-agent API (e.g., http://localhost:1234/v1)",
}, "http://localhost:1234/v1")
.field("agent.secondaryModelId", "string", {
displayName: "Sub-Agent Model ID",
subtitle: "Leave empty to use the currently loaded LM Studio model.",
}, "")
.field("agent.subAgentProfiles", "string", {
displayName: "Sub-Agent Profiles (JSON)",
subtitle: 'Custom prompts for roles like "coder", "reviewer"',
}, '{"summarizer": "You are a summarization expert.", "coder": "You are a software engineer."}')
.field("agent.subAgentFrequency", "string", {
displayName: "Sub-Agent Frequency (reserved)",
subtitle: "No longer auto-injects hints into chat. Sub-agent runs only when you ask or the model calls the tool.",
}, "never")
.field("agent.subAgentAllowFileSystem", "boolean", {
displayName: "Sub-Agent: Allow File System",
subtitle: "Let sub-agent read/write files",
}, true)
.field("agent.subAgentAllowWeb", "boolean", {
displayName: "Sub-Agent: Allow Web Search",
subtitle: "Let sub-agent search the web",
}, true)
.field("agent.subAgentAllowCode", "boolean", {
displayName: "Sub-Agent: Allow Code Execution",
subtitle: "Let sub-agent run code",
}, false)
.field("agent.subAgentAllowBrowserControl", "boolean", {
displayName: "Sub-Agent: Allow Browser Control",
subtitle: "Let sub-agent control browsers",
}, false)
.field("agent.subAgentTimeLimit", "numeric", {
int: true,
min: 30,
max: 3600,
displayName: "Sub-Agent Time Limit (sec)",
subtitle: "Maximum time for a single sub-agent task",
}, 600)
.field("wikipedia.enabled", "boolean", { displayName: "Enable Wikipedia Tool", subtitle: "" }, true)
.field("localRag.enabled", "boolean", { displayName: "Enable Local RAG", subtitle: "" }, false)
.field("retrieval.limit", "numeric", {
int: true,
min: 1,
max: 50,
displayName: "Retrieval Limit",
subtitle: "Maximum number of chunks to retrieve for RAG",
}, 5)
.field("retrieval.threshold", "numeric", {
min: 0.0,
max: 1.0,
step: 0.01,
displayName: "Retrieval Affinity Threshold",
subtitle: "Minimum cosine similarity score for a chunk to be returned",
}, 0.5)
.field("retrieval.embeddingModel", "string", {
displayName: "Embedding Model ID",
subtitle: "LM Studio model ID used for RAG embeddings and semantic memory",
}, "nomic-ai/nomic-embed-text-v1.5-GGUF")
.field("neo4j.uri", "string", {
displayName: "Neo4j URI",
subtitle: "Database connection string (e.g., neo4j://localhost:7687). Scheme is preserved.",
}, "")
.field("neo4j.username", "string", {
displayName: "Neo4j Username",
subtitle: "Default: neo4j",
}, "neo4j")
.field("neo4j.password", "string", {
displayName: "Neo4j Password (sensitive)",
subtitle: "Required for Neo4j tools and memory sync. Stored as plain text in settings.",
}, "")
.field("media.sharpWebpSupport", "boolean", {
displayName: "Enable WebP Support",
subtitle: "Allow WebP image format conversion",
}, true)
.field("media.ffmpegPath", "string", {
displayName: "FFmpeg Path (optional)",
subtitle: "Auto-detected if empty. Required for video/audio tools.",
}, "")
.field("archive.maxArchiveSizeMB", "numeric", {
int: true,
min: 100,
max: 5000,
displayName: "Max Archive Size (MB)",
subtitle: "Maximum allowed archive file size in megabytes",
}, 1024)
.field("automation.cronStoragePath", "string", {
displayName: "Cron Jobs Storage Path",
subtitle: "JSON file for persisting scheduled cron jobs",
}, "")
.field("automation.timeLogStoragePath", "string", {
displayName: "Time Log Storage Path",
subtitle: "File to store time tracking entries",
}, "")
.field("debug.enableDebugMode", "boolean", {
displayName: "Enable Debug Mode (Auto-Debug)",
subtitle: "Automatically review sub-agent code for bugs",
}, false)
.field("debug.enableSubAgentDebugLogging", "boolean", {
displayName: "Enable Sub-Agent Debug Logging",
subtitle: "Detailed logs for troubleshooting sub-agents",
}, false)
.field("debug.subAgentAutoSave", "boolean", {
displayName: "Sub-Agent Auto-Save",
subtitle: "Automatically save files generated by sub-agents",
}, true)
.field("debug.showFullCodeOutput", "boolean", {
displayName: "Show Full Code Output",
subtitle: "Display full code in chat (files are still saved)",
}, false)
.field("debug.simpleSystemPrompt", "boolean", {
displayName: "Simple System Prompt",
subtitle: "Use a simplified system prompt to save context window",
}, false)
.field("general.messageLanguage", "string", { displayName: "Message Language", subtitle: "Language for tool responses and status messages" }, resolvedLocale)
.field("general.uiLanguageOverride", "string", { displayName: "UI Language Override", subtitle: "Force UI language (default: auto)" }, "auto")
.build();