Project Files
src / config.ts
/**
* @file Merged config schematics — single chain combining tools + memory + media fields.
*
* IMPORTANT: The sub-namespace config exports (tools/config.ts → toolsPluginConfig,
* memory/config.ts → configSchematics) are still used by their respective modules
* via ctl.getPluginConfig(). Since SDK does structural key lookup at runtime,
* all keys present here will be readable through either sub-schematics object.
*/
import { createConfigSchematics } from "@lmstudio/sdk";
export const maestroConfigSchematics = createConfigSchematics()
// ── Tools Plugin Fields (from beledarian) ──────────────────────────
.field("defaultWorkingDirectory", "string", {
displayName: "🔧 Default Working Directory",
subtitle: "Starting directory when plugin loads. Leave empty for default (~/.maestro-toolbox/workspace). Applies on next chat.",
}, "")
.field("retrievalLimit", "numeric", {
int: true,
min: 1,
displayName: "🔧 Retrieval Limit",
subtitle: "When retrieval is triggered, this is the maximum number of chunks to return.",
slider: { min: 1, max: 10, step: 1 },
}, 3)
.field("retrievalAffinityThreshold", "numeric", {
min: 0.0,
max: 1.0,
displayName: "🔧 Retrieval Affinity Threshold",
subtitle: "The minimum similarity score for a chunk to be considered relevant.",
slider: { min: 0.0, max: 1.0, step: 0.01 },
}, 0.5)
.field("allowJavascriptExecution", "boolean", {
displayName: "⚡ Allow JavaScript Execution",
subtitle: "Enable the 'run_javascript' tool. DANGER: Code runs on your machine.",
}, false)
.field("allowPythonExecution", "boolean", {
displayName: "⚡ Allow Python Execution",
subtitle: "Enable the 'run_python' tool. DANGER: Code runs on your machine.",
}, false)
.field("allowTerminalExecution", "boolean", {
displayName: "⚡ Allow Terminal Execution",
subtitle: "Enable the 'run_in_terminal' tool. Opens real terminal windows.",
}, false)
.field("allowShellCommandExecution", "boolean", {
displayName: "⚡ Allow Shell Command Execution",
subtitle: "Enable the 'execute_command' tool. DANGER: Commands run on your machine.",
}, false)
.field("allowGitOperations", "boolean", {
displayName: "⚡ Allow Git Operations",
subtitle: "Enable git tools (status, commit, diff, log).",
}, true)
.field("allowDatabaseInspection", "boolean", {
displayName: "⚡ Allow Database Inspection",
subtitle: "Enable 'query_database' for SQLite files.",
}, false)
.field("allowSystemNotifications", "boolean", {
displayName: "⚡ Allow System Notifications",
subtitle: "Enable the agent to send OS notifications.",
}, true)
.field("allowAllCode", "boolean", {
displayName: "⚡ Allow All Code Execution",
subtitle: "MASTER SWITCH: Overrides all other settings to enable ALL execution tools.",
}, false)
.field("enableWikipediaTool", "boolean", {
displayName: "🌐 Enable Wikipedia Tool",
subtitle: "Enable the 'wikipedia_search' tool.",
}, true)
.field("enableSecondaryAgent", "boolean", {
displayName: "🤖 Enable Secondary Agent/Model",
subtitle: "Auto-detects a second loaded model via LM Link. If only one model is loaded, it delegates to itself.",
}, false)
.field("secondaryAgentEndpoint", "string", {
displayName: "🤖 Secondary Agent Endpoint",
subtitle: "API endpoint for the secondary model. Auto-detected model is used from this endpoint.",
}, "http://localhost:1234/v1")
.field("subAgentProfiles", "string", {
displayName: "🤖 Sub-Agent Profiles (JSON)",
subtitle: 'Define available sub-agents. Format: {"coder": "You are a coding expert...", ...}',
}, '{"summarizer": "You are a summarization expert. Summarize the content concisely.", "coder": "You are a software engineer. Write efficient and safe code."}')
.field("subAgentFrequency", "select", {
displayName: "🤖 Sub-Agent Frequency",
subtitle: "Controls how often the agent is encouraged to delegate tasks to the secondary agent.",
options: [
{ value: "when_useful", displayName: "When useful — delegate summarization, memory, research" },
{ value: "always", displayName: "Always — delegate all auxiliary tasks" },
{ value: "hard_tasks", displayName: "Hard tasks only — delegate sparingly" },
{ value: "never", displayName: "Never — disable delegation hints entirely" },
],
}, "when_useful")
.field("subAgentAllowFileSystem", "boolean", {
displayName: "🤖 Sub-Agent: Allow File System",
subtitle: "If enabled, sub-agents can read/list files.",
}, true)
.field("subAgentAllowWeb", "boolean", {
displayName: "🤖 Sub-Agent: Allow Web Search",
subtitle: "If enabled, sub-agents can use Wikipedia and DuckDuckGo.",
}, true)
.field("subAgentAllowCode", "boolean", {
displayName: "🤖 Sub-Agent: Allow Code Execution",
subtitle: "If enabled, sub-agents can run Python/JS code. DANGER!",
}, false)
.field("enableDebugMode", "boolean", {
displayName: "🤖 Enable Auto-Debug Mode",
subtitle: "If enabled, coding tasks delegated to sub-agents will automatically trigger a second 'Reviewer' pass to check for errors.",
}, false)
.field("subAgentAutoSave", "boolean", {
displayName: "🤖 Sub-Agent: Auto-Save Code",
subtitle: "If enabled, code blocks generated by the sub-agent that aren't explicitly saved will be automatically saved to files.",
}, true)
.field("showFullCodeOutput", "boolean", {
displayName: "🤖 Show Full Code Output",
subtitle: "If enabled, the Main Agent will display the full code content of generated files instead of just the file paths.",
}, false)
// ── Persistent Memory Fields (from dirty-data) ─────────────────────
.field("autoInjectMemories", "select", {
displayName: "🧠 Auto-Inject Memories",
subtitle: "Automatically add relevant memories to every conversation (via prompt preprocessor)",
options: [
{ value: "on", displayName: "On — inject relevant memories automatically (recommended)" },
{ value: "off", displayName: "Off — only recall when explicitly asked via tools" },
],
}, "on")
.field("contextMemoryCount", "numeric", {
displayName: "🧠 Context Memory Count",
subtitle: "How many memories to inject per message when auto-inject is on (1–15)",
min: 1,
max: 15,
int: true,
slider: { step: 1, min: 1, max: 15 },
}, 5)
.field("enableAIExtraction", "select", {
displayName: "🧠 AI Fact Extraction",
subtitle: "Use the loaded model to automatically extract facts from conversations",
options: [
{ value: "on", displayName: "On — AI extracts facts from your messages" },
{ value: "off", displayName: "Off — only store what you explicitly tell it to remember" },
],
}, "on")
.field("enableConflictDetection", "select", {
displayName: "🧠 Conflict Detection",
subtitle: "Use AI to detect contradictions between new and existing memories",
options: [
{ value: "on", displayName: "On — detect and handle conflicting memories" },
{ value: "off", displayName: "Off — store everything without checking" },
],
}, "on")
.field("decayHalfLifeDays", "numeric", {
displayName: "🧠 Memory Decay Half-Life (days)",
subtitle: "How many days until an un-accessed memory loses half its retrieval priority (7–365)",
min: 7,
max: 365,
int: true,
slider: { step: 7, min: 7, max: 365 },
}, 30)
.field("memoryStoragePath", "string", {
displayName: "🧠 Storage Path (advanced)",
subtitle: "Custom directory for the memory database. Leave empty for default (~/.lmstudio/plugin-data/persistent-memory/)",
}, "")
.field("activeProject", "string", {
displayName: "🧠 Active Project",
subtitle: "Stable project slug for project-scoped retrieval and writes. When set, project memories for this project are auto-injected and AI-extracted durable facts inherit this project.",
}, "")
.field("memoryInjectionCategories", "string", {
displayName: "🧠 Injection Category Filter",
subtitle: "Comma-separated list of categories to auto-inject (e.g. 'preference,fact,project'). Leave empty for all categories.",
}, "")
// ── Visual/Design Fields ──────────────────────────────────
.field("enableDesignMode", "boolean", {
displayName: "🎨 Enable Design Mode",
subtitle: "Injects design knowledge + 58 real design systems (Apple, Figma, Notion, etc.) the model can load on demand.",
}, false)
// ── Media Tools Fields (new) ──────────────────────────────────
.field("enableImageAnalysis", "boolean", {
displayName: "📷 Enable Image Analysis",
subtitle: "Enable the analyze_image tool to describe images from local paths.",
}, true)
.field("imageMaxDimension", "numeric", {
displayName: "📷 Image Max Dimension (px)",
subtitle: "Maximum width or height for image analysis. Lower = less tokens, faster.",
int: true,
min: 128,
max: 1280,
slider: { min: 128, max: 1280, step: 64 },
}, 512)
.field("enableVideoAnalysis", "boolean", {
displayName: "🎬 Enable Video Analysis",
subtitle: "Enable the analyze_video tool to extract and analyze frames from local video files. Requires ffmpeg.",
}, true)
.field("videoFrameCount", "numeric", {
displayName: "🎬 Video Frame Count",
subtitle: "Number of frames to extract for video analysis (1–10).",
int: true,
min: 1,
max: 10,
slider: { min: 1, max: 10, step: 1 },
}, 4)
.field("videoFrameMaxDimension", "numeric", {
displayName: "🎬 Video Frame Max Dimension (px)",
subtitle: "Maximum width or height of extracted video frames. Lower = faster analysis.",
int: true,
min: 128,
max: 1280,
slider: { min: 128, max: 1280, step: 64 },
}, 384)
.build();