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/low → Low, medium → Medium, high → High, xhigh → Max, 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.
Summary
render_chat()maps every acceptedreasoning_effortvalue except"high"ontoMax:The endpoint accepts
none, minimal, low, medium, high, xhigh. Of the five that enable thinking, four renderMax— includingminimalandlow. A client asking for the least reasoning gets the most.The ordering is not merely coarse, it is non-monotonic:
minimallowmediumhighxhighMeasured, 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:reasoning_effort, noenable_thinking)reasoning_effort=highreasoning_effort=xhigh→ rendersMaxCOLI_THINK=1So the two levels are real and distinguishable —
Maxgenuinely produces more reasoning thanHigh. Which makes the inversion a behaviour change rather than a cosmetic one: a client throttling tominimalto save tokens gets the most expensive setting available.Second, related:
COLI_THINK=1cannot reachMaxCOLI_THINKis 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 noReasoning Effortline 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/low→Low,medium→Medium,high→High,xhigh→Max, or whatever ladder the template actually supports; I have only verified thatHighandMaxare both accepted and behave differently. And lettingCOLI_THINKcarry a level (COLI_THINK=max) rather than being boolean, with1keeping 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, modelmastouri/GLM-5.2-colibri-int4-g64-with-int8-mtp.