Custom models were pinned reasoning:false, so every one of them offered a
single thinking level ("off") while built-in reasoning models offered the
standard ladder. The endpoint's /models metadata now decides:
- detectReasoning() trusts explicit metadata only — a boolean
reasoning / supports_reasoning / thinking, or a reasoning token in
supported_parameters (vLLM, OpenRouter), capabilities, tags or
architecture.output_modalities. No name guessing: a false positive would
send reasoning_effort to a server that rejects it.
- CustomModel carries the detected flag (persisted, sanitizer keeps it),
toPiModel passes it through, and pi-ai does the rest — default
off/minimal/low/medium/high set, reasoning_effort on the wire.
Verified in the browser against a local OpenAI-compatible mock: the
reasoning-capable model exposes off/minimal/low/medium/high, the plain one
stays at off, and a prompt with medium actually arrives as
reasoning_effort=medium.