POST /v1/chat/completions now accepts
reasoning_effort (minimal | low | medium |
high | xhigh | max) and include_reasoning,
and translates them to whatever the model that serves the request actually takes —
output_config.effort for Claude, reasoning_effort for OpenAI reasoning
models, and nothing at all for models with no reasoning control, which is reported in the log
rather than silently dropped. A level the model does not accept is mapped to the nearest one it
does: the mapping never resolves to a cheaper level than the caller asked for, so a request for
max cannot quietly become low.
Thinking configuration moved from the protocol to the model, because the models no longer
share one shape. Claude Sonnet 5, Opus 4.7/4.8 and the Fable line reject
thinking: {type: "enabled", budget_tokens: N} and require
thinking: {type: "adaptive"} with an effort. A budget sent to one of those is
converted to adaptive with the depth carried across in effort, instead of being
forwarded and failing with a 400. display: "summarized" is only sent when
reasoning text was actually asked for — sending it otherwise made the provider return an empty
thinking block.
Two fixes behind it. The interleaved-thinking beta flag was being put in the request body,
where it is ignored; it now travels as an anthropic-beta header. And sampling
parameters are withheld per model rather than per request: the API rejects
temperature, top_p and top_k when thinking is on — and
rejects the first two on the adaptive models whether or not thinking was requested — so they are
omitted rather than forwarded to fail.