{ "id": "lm-studio", "role": "reviewer", "version": "2.0.0", "title": "LM Studio", "description": "LM Studio local model server — cross-AI /msd:review reviewer lane only; not a MSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.lm_studio_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`lm-studio`, required by KEBAB_RE); `reviewer.slug` stays snake (`lm_studio`) to match the shipped roster and the `review.lm_studio_host` config key (ADR-2782's three-namespace trap).", "tier": "full", "requires": [], "engines": { "msd": ">=1.8.0" }, "reviewer": { "slug": "lm_studio", "flags": [ "--lm-studio" ], "transport": "openai-http", "probe": { "kind": "http-reachable", "hostConfigKey": "review.lm_studio_host", "path": "/v1/models", "timeoutMs": 2000 }, "invoke": { "hostConfigKey": "review.lm_studio_host", "defaultHost": "http://localhost:1234", "path": "/v1/chat/completions", "modelDiscovery": "first-from-models-endpoint", "fallbackModel": "local-model", "effortChannel": "none" }, "timeoutFloorMs": 120000, "timeoutConfigKey": "review.timeouts.lm_studio", "emptyOutput": "stub-with-stderr", "reviewsSection": "LM Studio", "evidenceClass": "source-grounded", "requiresBinaries": [], "promptBudgetKey": "review.max_prompt_tokens_per_reviewer.lm_studio", "modelConfigKey": "review.models.lm_studio", "effortConfigKey": null, "defaultEffort": null, "handler": "openai-compatible" }, "config": { "review.models.lm_studio": { "type": "string", "default": "", "description": "Model requested from the LM Studio reviewer lane; empty discovers the first model from /v1/models." }, "review.lm_studio_host": { "type": "string", "default": "", "description": "Base URL of the LM Studio OpenAI-compatible server." }, "review.max_prompt_tokens_per_reviewer.lm_studio": { "type": "number", "default": -1, "description": "Prompt-token budget for the LM Studio reviewer lane. Unset is -1, a sentinel: 0 is a legitimate value meaning \"do not trim this lane\", so it cannot double as \"not configured\"." }, "review.timeouts.lm_studio": { "type": "number", "default": -1, "description": "Outer wall-clock timeout override (seconds) for the LM Studio reviewer lane. Unset is -1, a sentinel: 0 or a negative number is also treated as unset (a timeout has no legitimate zero/negative value), so no second sentinel is needed. Falls back to the lane's built-in timeoutFloorMs when unset." } } }