Skip to content

[Bug]: reasoning_effort is inverted below "high" — minimal/low/medium all render "Reasoning Effort: Max" #809

Description

@ThefloorMiner

Summary

render_chat() maps every accepted reasoning_effort value except "high" onto Max:

if enable_thinking:
    effort = "High" if reasoning_effort == "high" else "Max"
    prompt.append(f"<|system|>Reasoning Effort: {effort}")

The endpoint accepts none, minimal, low, medium, high, xhigh. Of the five that enable thinking, four render Max — including minimal and low. A client asking for the least reasoning gets the most.

The ordering is not merely coarse, it is non-monotonic:

requested rendered
minimal Max
low Max
medium Max
high High
xhigh Max

Measured, so this is not a reading of the source alone

GLM-5.2 744B on 4× RTX A6000, same prompt with a tool declaration, temperature 0, measuring the length of the returned reasoning block:

condition reasoning emitted
default (no reasoning_effort, no enable_thinking) none
reasoning_effort=high 120 chars
reasoning_effort=xhigh → renders Max 178 chars
COLI_THINK=1 120 chars

So the two levels are real and distinguishable — Max genuinely produces more reasoning than High. Which makes the inversion a behaviour change rather than a cosmetic one: a client throttling to minimal to save tokens gets the most expensive setting available.

Second, related: COLI_THINK=1 cannot reach Max

if (reasoning_effort is None and "enable_thinking" not in body
        and os.environ.get("COLI_THINK", "0") == "1"):
    reasoning_effort = "high"

COLI_THINK is the operator-side switch for clients that send neither field — which is the common case; Open WebUI, for one, sends neither. It hard-codes "high", so an operator can turn thinking on but cannot select the level, and specifically cannot select the one level the code goes out of its way to support.

Why this is easy to miss

The default path is enable_thinking=False, and then no Reasoning Effort line is emitted at all. So on a stock deployment the mapping is unreachable: you get no reasoning, which looks like "the model does not think" rather than "the effort ladder is inverted". I only found it because I went looking for why a deployment had never once emitted a reasoning block.

Suggested shape

An ordered mapping rather than a two-way branch — minimal/lowLow, mediumMedium, highHigh, xhighMax, or whatever ladder the template actually supports; I have only verified that High and Max are both accepted and behave differently. And letting COLI_THINK carry a level (COLI_THINK=max) rather than being boolean, with 1 keeping today's meaning.

Happy to send that as a PR if the ladder above is the one you want. I did not open with a patch because the set of levels GLM-5.2 accepts is a question about the model, not the code, and you will know it better than my two measured points do.


Observed on dev @ 7fb1159, Linux, CUDA build sm_86, 4× RTX A6000, model mastouri/GLM-5.2-colibri-int4-g64-with-int8-mtp.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugDifetto verificato nel codicequalityQualità del modello / quantizzazione

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions