Skip to content

core: LM Studio model discovery fails silently with decision-type models #56213

Description

@tomzhu1024

Description

When LM Studio's library contains a decision-type model (e.g. clef-flash), model discovery fails silently and no LM Studio models show up in opencode.

Plugins

N/A

OpenCode version

2.0.29

Steps to reproduce

  1. In LM Studio, download an LLM and a decision model
  2. Start the LM Studio server (default port 1234)
  3. Run opencode models -- no LM Studio models appear, no errors logged.

Screenshot and/or share link

No response

Operating System

macOS 27.0.1

Terminal

iTerm2

Activity

  1. opencode-agent commented on Oct 16, 2026

    @opencode-agent
    Contributor

    Thanks for the report. I reproduced this on 2.0.29 and on the latest release, 2.0.31.

    I used a mock LM Studio server on port 1234 whose /api/v1/models returns one LLM (qwen/qwen3-8b) plus one model with "type": "decision" (clef-flash):

    • With the decision model in the response, opencode models shows no lmstudio/... models and no error, even across several 30s discovery refreshes.
    • When the decision entry is removed, lmstudio/qwen/qwen3-8b appears after the next refresh.

    The LM Studio discovery code only accepts the model types llm and embedding, and it validates the whole response before filtering out non-LLM models. One decision model therefore makes the whole response fail, and the error is swallowed. That code is unchanged on the current dev branch (bc5ebf0), so it should behave the same there. I couldn't run dev from source to confirm. Open PR #56214 targets this.

    The script below reproduces it.

    Reproduction script (repro.sh)
    #!/usr/bin/env bash
    # Reproduces #56213: a single decision-type model in LM Studio's
    # /api/v1/models response hides every LM Studio model from `opencode models`.
    # Usage: ./repro.sh                                  (uses `opencode` from PATH)
    #        OC_DEV=/path/to/opencode/checkout ./repro.sh (runs from source)
    # Needs: bun, curl, port 1234 free. Kills any running `opencode serve --service`
    # so discovery starts from scratch.
    set -u
    DIR=$(mktemp -d)
    cd "$DIR"
    
    run_opencode() {
      if [ -n "${OC_DEV:-}" ]; then
        bun --conditions=browser --preload="$OC_DEV/packages/tui/node_modules/@opentui/solid/scripts/preload.js" "$OC_DEV/packages/cli/src/index.ts" "$@"
      else
        opencode "$@"
      fi
    }
    
    cat > server.ts <<'EOF'
    import { readFileSync } from "node:fs"
    const llm = {
      type: "llm", key: "qwen/qwen3-8b", display_name: "Qwen3 8B", architecture: "qwen3",
      loaded_instances: [], max_context_length: 32768,
      capabilities: { vision: false, trained_for_tool_use: true },
    }
    const decision = {
      type: "decision", key: "clef-flash", display_name: "Clef Flash",
      loaded_instances: [], max_context_length: 8192,
    }
    Bun.serve({
      port: 1234, hostname: "127.0.0.1",
      fetch(req) {
        const url = new URL(req.url)
        const withDecision = readFileSync("mode", "utf8").trim() === "1"
        console.error(new Date().toISOString(), "mock:", req.method, url.pathname, "decision =", withDecision)
        if (url.pathname === "/api/v1/models")
          return Response.json({ models: withDecision ? [llm, decision] : [llm] })
        return new Response("not found", { status: 404 })
      },
    })
    EOF
    
    check() {
      # discovery runs in the background service and refreshes every 30s; poll for ~40s
      for i in $(seq 1 8); do
        out=$(run_opencode models 2>&1 | grep -i '^lmstudio/' || true)
        echo "  [$(date -u +%T)] lmstudio models: ${out:-<none>}"
        sleep 5
      done
    }
    
    pkill -f 'opencode.* serve --service' 2>/dev/null; sleep 1
    echo 1 > mode
    bun server.ts 2>server.log &
    PID=$!
    until curl -sf http://127.0.0.1:1234/api/v1/models >/dev/null; do sleep 0.2; done
    
    echo "=== LM Studio returns 1 llm + 1 decision model ==="
    check
    echo 0 > mode
    echo "=== LM Studio returns only the llm model ==="
    check
    
    kill $PID
    echo "--- mock server log:"; cat server.log

    Run it: bash repro.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions