Skip to content

web / desktop client: model tooltip shows "No reasoning" for models that expose reasoning variants #56317

Closed as duplicate

Description

@xuyongroger

Description

Summary

In the web / desktop client, the model list tooltip always shows Reasoning: "No reasoning" (zh: 不支持推理) for every model, even when the model actually supports reasoning and the server returns reasoning variants.

The web client's V2 → legacy model adapter hard-codes capabilities.reasoning = false while building its model objects from /api/model, so anything that reads capabilities.reasoning (the model tooltip) can never report reasoning support. Since reasoning is now expressed as generated variants, the client should derive support from variants.length.

Environment

  • opencode version: 2.0.31 (opencode --version)
  • OS: Linux 0e46af3aca03 5.19.17-z4pro-generic x86_64 (server runs in a Docker container; client is the OpenCode web/desktop UI on the LAN)
  • Terminal: Unavailable (browser / desktop client; server process TERM=xterm-256color)
  • Shell: Unavailable ($SHELL not set in the container)
  • Install/channel: release / latest, /usr/local/bin/opencode, started as opencode serve --hostname 0.0.0.0 --port 4096; the managed opencode serve --service is also 2.0.31
  • Active plugins: auto-discovered local plugin ~/.config/opencode/plugins/searxng; no plugins entries in opencode.json
  • Config used for repro (secrets and internal hostnames redacted):
{
  "providers": {
    "acme": {
      "name": "Local Flash Server",
      "package": "@opencode/ai/providers/openai-compatible",
      "settings": { "baseURL": "https://llm.internal.example/v1", "apiKey": "<redacted>" },
      "models": {
        "qwen-flash": {
          "name": "Qwen Flash",
          "settings": { "reasoningEffort": "xhigh" },
          "capabilities": {
            "reasoning": { "supported": true, "effort": ["low", "medium", "xhigh", "none"] },
            "tools": true,
            "input": ["text", "image"],
            "output": ["text"]
          },
          "limit": { "context": 262144, "input": 229376, "output": 32768 }
        }
      }
    }
  }
}

Reproduction

  1. Declare reasoning controls on a model via capabilities.reasoning (config above), then restart the server or run /reload.
  2. Verify the server side: GET /api/model returns the generated variants for that model.
  3. Open the web UI (served by the same server on :4096), or the desktop app pointed at that server, and open the model dropdown.
  4. Look at the reasoning line of the model tooltip.

Expected Behavior

Tooltip shows "Allows reasoning" (支持推理) and the model's reasoning variants (#low / #medium / #xhigh / #none) are offered, since the model does stream reasoning.

Actual Behavior

Tooltip shows "No reasoning" (不支持推理). The model is fully functional: the same session produces reasoning parts and tokens.reasoning > 0, and the server exposes the variants. The TUI is unaffected because it computes support as model.variants.length > 0.

Consistent, 100% reproducible.

Additional Context

Server response for the model (redacted, note capabilities has no reasoning field and variants are present):

{
  "id": "qwen-flash",
  "modelID": "qwen-flash",
  "providerID": "acme",
  "settings": { "reasoningEffort": "xhigh" },
  "capabilities": { "tools": true, "input": ["text", "image"], "output": ["text"] },
  "variants": [
    { "id": "low", "settings": { "reasoningEffort": "low" } },
    { "id": "medium", "settings": { "reasoningEffort": "medium" } },
    { "id": "xhigh", "settings": { "reasoningEffort": "xhigh" } },
    { "id": "none", "settings": { "reasoningEffort": "none" } }
  ]
}

Evidence that reasoning really streams for that model in the same session:

GET /api/session/<session>/message
- 38 parts with "type":"reasoning"
- assistant usage: "tokens":{"input":575,"output":116,"reasoning":147,"cache":{"read":74098,"write":0}}

Client-side cause, from the web bundle served at /_assets/runtime-*.js (minified, formatting added):

t.models[e.id] = {
  id: e.id,
  providerID: e.providerID,
  api: { id: e.modelID, url: "", npm: e.package ?? t.id },
  name: e.name,
  family: e.family,
  capabilities: {
    temperature: false,
    reasoning: false,          // <-- hard-coded, ignores e.variants
    attachment: e.capabilities.input.some((x) => x !== "text"),
    toolcall: e.capabilities.tools,
    input: { ... },
    output: { ... },
  },
  // variants are mapped correctly right next to it:
  variants: Object.fromEntries(e.variants.map((v) => [v.id, v.settings ?? {}])),
};

And the i18n keys that render the tooltip line:

"model.tooltip.reasoning":          "Reasoning"        / 推理
"model.tooltip.reasoning.allowed":  "Allows reasoning"  / 支持推理
"model.tooltip.reasoning.none":     "No reasoning"      / 不支持推理

Notes:

  • The V2 Model.Capabilities schema only has tools, input, output, temperature; after the "generate reasoning variants from reasoning options" change, reasoning capability is expressed exclusively through variants. Any client (or V1-shape adapter) that reads capabilities.reasoning will therefore always read false.
  • Suggested fix: derive the flag in the adapter (or wherever the tooltip reads it) from model.variants.length > 0, the same way the TUI already does, or expose an explicit reasoning flag in the API model payload.
  • Workaround / non-blocker: variants are honoured regardless of the tooltip, e.g. opencode run --model acme/qwen-flash#low "hi"; the default settings.reasoningEffort from config is applied as well.

Plugins

No response

OpenCode version

No response

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. opencode-agent commented on Oct 17, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report and for tracing it to the client adapter! I think this is a duplicate of #50257. It reports the same bug: every v2 model's tooltip shows "No reasoning" because the app's model mapper (packages/app/src/runtime/server/global-sync/utils.ts, used by both the web UI and the desktop app) hard-codes capabilities.reasoning: false, and the v2 model payload never includes a reasoning flag. PR #55100 is open to fix it and takes the second approach you suggested: it adds the reasoning flag to the model payload.

    Possible duplicates and related issues, most likely first:

    The bot will close this issue as a duplicate of #50257 in 1 day unless you reply explaining how your problem is different. Following #50257 and #55100 is the best way to get updates.

  2. opencode-agent commented on Oct 18, 2026

    @opencode-agent
    Contributor

    We haven't heard back, so I'm closing this as a duplicate of #50257. That issue covers the same bug: the model tooltip shows "No reasoning" for every v2 model because the shared web/desktop model mapper hard-codes capabilities.reasoning: false, and the v2 model payload has no reasoning flag. Please follow #50257 and the open fix PR #55100 for updates. If your case turns out to be different, reply here and explain how, and we can reopen. Thanks again for the thorough analysis!

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