src / config.ts
src / config.ts
import { createConfigSchematics } from "@lmstudio/sdk";
export const defaultPluginSettings = {
PREVIEW_IN_CHAT: true,
HTTP_SERVER_PORT: 54760,
embeddingBaseUrl: "http://127.0.0.1:1234/v1",
embeddingApiKey: "",
qwen3VlModelPath: "qwen/qwen3-vl-8b",
visionPrompt: "",
embedPngMetadata: true,
serverMaxTokens: 768,
serverTemperature: 0.7,
qwen3VlOdPrompt: [
"Detect objects in the image with strict hierarchical prioritization.",
"",
"PRIORITY 1 (CRITICAL - MUST DETECT FIRST):",
'- You MUST detect "human face" (highest priority if a person is present)',
'- You MUST detect "person" (if no face is clearly visible or if the person is the main subject)',
"",
"PRIORITY 2 (MAIN SUBJECT / HERO ELEMENT):",
"- The most visually prominent object or subject that is NOT part of the background.",
"- Use specific, concrete labels (e.g., 'red car', 'fluffy owl toy').",
"- Avoid generic terms like 'object' or 'thing'.",
"",
"PRIORITY 3 (CONTEXTUAL BACKGROUND ELEMENTS):",
"- Only detect background elements if they are significant to the scene composition OR if the main subject is interacting with them.",
"- Do not detect minor or redundant background details.",
"",
"PRIORITY 4 (FOCUSSED MAIN SUBJECT / HERO ELEMENT):",
"- All visible body parts (hands, feet, arms, legs).",
"- Elements of the face, as far as clearly detectable and focussed on close-ups: nose, mouth, left and right eyes, eyebrows and ears",
"- anatomical details, as far as recognizable as \\\"focussed\\\" or \\\"prominent\\\" (e.g., 'iris', 'pupil', 'eyelid')",
"",
"RULES:",
"- Maximum 16 objects total.",
"- Each bounding box must be unique and non-redundant.",
"- For clothing, name the specific garment (e.g., 'tank top', 'jeans').",
"- For body parts, qualify by position (e.g., 'left hand').",
"- NEVER prioritize background elements over the main subject or human face.",
"- NEVER prioritize anatomical details over general concepts unless they are solely focussed (e.g. only detect 'eyes' unless 'human face' is the dominant part of the image)",
"- If the main subject is a person, focus on the person and their immediate interactions. Ignore background elements unless they are directly involved in the interaction.",
"- If NO person or face is visible, ALWAYS detect Priority 2 and Priority 3 subjects regardless.",
].join("\n"),
detectMaxTokens: 2048,
detectTemperature: 0.3,
includeGenerationMetadata: true,
} as const;
export const globalConfigSchematics = createConfigSchematics()
.field(
"PREVIEW_IN_CHAT",
"boolean",
{
displayName: "Previews in Chat",
subtitle: "When enabled, tool responses include inline image previews. Recommended for local models without vision capability.",
engineDoesNotSupport: false,
},
defaultPluginSettings.PREVIEW_IN_CHAT
)
.field(
"HTTP_SERVER_PORT",
"numeric",
{
displayName: "Local HTTP Server Port",
subtitle: "Port for serving generated images over localhost (default: 54760).",
engineDoesNotSupport: true,
},
defaultPluginSettings.HTTP_SERVER_PORT
)
.field(
"embeddingBaseUrl",
"string",
{
displayName: "Vision API Base URL",
subtitle: "OpenAI-compatible /v1 URL. Vision tools use the same server root and call LM Studio's internal /api/v1 vision endpoints. Separate from the agent API.",
placeholder: "http://127.0.0.1:1234/v1",
engineDoesNotSupport: false,
},
defaultPluginSettings.embeddingBaseUrl
)
.field(
"embeddingApiKey",
"string",
{
displayName: "Vision API Key",
subtitle: "Optional key for the Qwen3-VL vision backend. Separate from the agent API key.",
isProtected: true,
placeholder: "sk-...",
engineDoesNotSupport: false,
},
defaultPluginSettings.embeddingApiKey
)
.field(
"qwen3VlModelPath",
"string",
{
displayName: "Qwen3-VL Model",
subtitle: "LM Studio model key for the Qwen3-VL Vision API backend, for example qwen/qwen3-vl-8b. This is not a filesystem path.",
placeholder: "qwen/qwen3-vl-8b",
engineDoesNotSupport: false,
},
defaultPluginSettings.qwen3VlModelPath
)
.field(
"visionPrompt",
"string",
{
displayName: "Vision Prompt",
subtitle: "Default prompt sent to the vision model when the agent does not supply one. Leave empty to disable automatic visual description.",
placeholder: "Analyze this image based strictly on what is directly visible. Do not infer, assume, or complete information that is not present.",
isParagraph: true,
},
defaultPluginSettings.visionPrompt
)
.field(
"embedPngMetadata",
"boolean",
{
displayName: "Embed Metadata in PNGs",
subtitle: "Write analysis provenance, detected objects, and bounding boxes into saved PNGs as Draw Things-compatible XMP metadata.",
engineDoesNotSupport: false,
},
defaultPluginSettings.embedPngMetadata
)
.field(
"includeGenerationMetadata",
"boolean",
{
displayName: "Include Generation Metadata",
subtitle: "When enabled, Draw Things generation parameters (prompt, model, sampler, seed, ...) embedded in PNG files are appended to each analysis result.",
engineDoesNotSupport: false,
},
defaultPluginSettings.includeGenerationMetadata
)
.field(
"serverMaxTokens",
"numeric",
{
displayName: "Vision API: Max Tokens",
subtitle: "Maximum response length in tokens (1-4096). Default: 768.",
engineDoesNotSupport: true,
},
defaultPluginSettings.serverMaxTokens
)
.field(
"serverTemperature",
"numeric",
{
displayName: "Vision API: Temperature",
subtitle: "Sampling temperature (0.0-2.0). Default: 0.7.",
engineDoesNotSupport: true,
},
defaultPluginSettings.serverTemperature
)
.field(
"qwen3VlOdPrompt",
"string",
{
displayName: "Qwen3-VL: Object Detection Prompt",
subtitle: "Instruction sent to Qwen3-VL for default object detection. Leave empty to use the built-in default.",
placeholder: "",
isParagraph: true,
engineDoesNotSupport: false,
},
defaultPluginSettings.qwen3VlOdPrompt
)
.field(
"detectMaxTokens",
"numeric",
{
displayName: "Vision API Detect: Max Tokens",
subtitle: "Maximum response length in tokens for object detection (1-4096). Default: 2048.",
engineDoesNotSupport: true,
},
defaultPluginSettings.detectMaxTokens
)
.field(
"detectTemperature",
"numeric",
{
displayName: "Vision API Detect: Temperature",
subtitle: "Sampling temperature for object detection (0.0-2.0). Default: 0.3.",
engineDoesNotSupport: true,
},
defaultPluginSettings.detectTemperature
)
.build();
import { createConfigSchematics } from "@lmstudio/sdk";
export const defaultPluginSettings = {
PREVIEW_IN_CHAT: true,
HTTP_SERVER_PORT: 54760,
embeddingBaseUrl: "http://127.0.0.1:1234/v1",
embeddingApiKey: "",
qwen3VlModelPath: "qwen/qwen3-vl-8b",
visionPrompt: "",
embedPngMetadata: true,
serverMaxTokens: 768,
serverTemperature: 0.7,
qwen3VlOdPrompt: [
"Detect objects in the image with strict hierarchical prioritization.",
"",
"PRIORITY 1 (CRITICAL - MUST DETECT FIRST):",
'- You MUST detect "human face" (highest priority if a person is present)',
'- You MUST detect "person" (if no face is clearly visible or if the person is the main subject)',
"",
"PRIORITY 2 (MAIN SUBJECT / HERO ELEMENT):",
"- The most visually prominent object or subject that is NOT part of the background.",
"- Use specific, concrete labels (e.g., 'red car', 'fluffy owl toy').",
"- Avoid generic terms like 'object' or 'thing'.",
"",
"PRIORITY 3 (CONTEXTUAL BACKGROUND ELEMENTS):",
"- Only detect background elements if they are significant to the scene composition OR if the main subject is interacting with them.",
"- Do not detect minor or redundant background details.",
"",
"PRIORITY 4 (FOCUSSED MAIN SUBJECT / HERO ELEMENT):",
"- All visible body parts (hands, feet, arms, legs).",
"- Elements of the face, as far as clearly detectable and focussed on close-ups: nose, mouth, left and right eyes, eyebrows and ears",
"- anatomical details, as far as recognizable as \\\"focussed\\\" or \\\"prominent\\\" (e.g., 'iris', 'pupil', 'eyelid')",
"",
"RULES:",
"- Maximum 16 objects total.",
"- Each bounding box must be unique and non-redundant.",
"- For clothing, name the specific garment (e.g., 'tank top', 'jeans').",
"- For body parts, qualify by position (e.g., 'left hand').",
"- NEVER prioritize background elements over the main subject or human face.",
"- NEVER prioritize anatomical details over general concepts unless they are solely focussed (e.g. only detect 'eyes' unless 'human face' is the dominant part of the image)",
"- If the main subject is a person, focus on the person and their immediate interactions. Ignore background elements unless they are directly involved in the interaction.",
"- If NO person or face is visible, ALWAYS detect Priority 2 and Priority 3 subjects regardless.",
].join("\n"),
detectMaxTokens: 2048,
detectTemperature: 0.3,
includeGenerationMetadata: true,
} as const;
export const globalConfigSchematics = createConfigSchematics()
.field(
"PREVIEW_IN_CHAT",
"boolean",
{
displayName: "Previews in Chat",
subtitle: "When enabled, tool responses include inline image previews. Recommended for local models without vision capability.",
engineDoesNotSupport: false,
},
defaultPluginSettings.PREVIEW_IN_CHAT
)
.field(
"HTTP_SERVER_PORT",
"numeric",
{
displayName: "Local HTTP Server Port",
subtitle: "Port for serving generated images over localhost (default: 54760).",
engineDoesNotSupport: true,
},
defaultPluginSettings.HTTP_SERVER_PORT
)
.field(
"embeddingBaseUrl",
"string",
{
displayName: "Vision API Base URL",
subtitle: "OpenAI-compatible /v1 URL. Vision tools use the same server root and call LM Studio's internal /api/v1 vision endpoints. Separate from the agent API.",
placeholder: "http://127.0.0.1:1234/v1",
engineDoesNotSupport: false,
},
defaultPluginSettings.embeddingBaseUrl
)
.field(
"embeddingApiKey",
"string",
{
displayName: "Vision API Key",
subtitle: "Optional key for the Qwen3-VL vision backend. Separate from the agent API key.",
isProtected: true,
placeholder: "sk-...",
engineDoesNotSupport: false,
},
defaultPluginSettings.embeddingApiKey
)
.field(
"qwen3VlModelPath",
"string",
{
displayName: "Qwen3-VL Model",
subtitle: "LM Studio model key for the Qwen3-VL Vision API backend, for example qwen/qwen3-vl-8b. This is not a filesystem path.",
placeholder: "qwen/qwen3-vl-8b",
engineDoesNotSupport: false,
},
defaultPluginSettings.qwen3VlModelPath
)
.field(
"visionPrompt",
"string",
{
displayName: "Vision Prompt",
subtitle: "Default prompt sent to the vision model when the agent does not supply one. Leave empty to disable automatic visual description.",
placeholder: "Analyze this image based strictly on what is directly visible. Do not infer, assume, or complete information that is not present.",
isParagraph: true,
},
defaultPluginSettings.visionPrompt
)
.field(
"embedPngMetadata",
"boolean",
{
displayName: "Embed Metadata in PNGs",
subtitle: "Write analysis provenance, detected objects, and bounding boxes into saved PNGs as Draw Things-compatible XMP metadata.",
engineDoesNotSupport: false,
},
defaultPluginSettings.embedPngMetadata
)
.field(
"includeGenerationMetadata",
"boolean",
{
displayName: "Include Generation Metadata",
subtitle: "When enabled, Draw Things generation parameters (prompt, model, sampler, seed, ...) embedded in PNG files are appended to each analysis result.",
engineDoesNotSupport: false,
},
defaultPluginSettings.includeGenerationMetadata
)
.field(
"serverMaxTokens",
"numeric",
{
displayName: "Vision API: Max Tokens",
subtitle: "Maximum response length in tokens (1-4096). Default: 768.",
engineDoesNotSupport: true,
},
defaultPluginSettings.serverMaxTokens
)
.field(
"serverTemperature",
"numeric",
{
displayName: "Vision API: Temperature",
subtitle: "Sampling temperature (0.0-2.0). Default: 0.7.",
engineDoesNotSupport: true,
},
defaultPluginSettings.serverTemperature
)
.field(
"qwen3VlOdPrompt",
"string",
{
displayName: "Qwen3-VL: Object Detection Prompt",
subtitle: "Instruction sent to Qwen3-VL for default object detection. Leave empty to use the built-in default.",
placeholder: "",
isParagraph: true,
engineDoesNotSupport: false,
},
defaultPluginSettings.qwen3VlOdPrompt
)
.field(
"detectMaxTokens",
"numeric",
{
displayName: "Vision API Detect: Max Tokens",
subtitle: "Maximum response length in tokens for object detection (1-4096). Default: 2048.",
engineDoesNotSupport: true,
},
defaultPluginSettings.detectMaxTokens
)
.field(
"detectTemperature",
"numeric",
{
displayName: "Vision API Detect: Temperature",
subtitle: "Sampling temperature for object detection (0.0-2.0). Default: 0.3.",
engineDoesNotSupport: true,
},
defaultPluginSettings.detectTemperature
)
.build();