Native reasoning controls and history
CompletionConfig accepts six distinct ReasoningEffort values. Lowercase string
values also work. Leaving reasoning_effort=None sends no reasoning control;
this does not mean reasoning is disabled or imply equivalent provider defaults.
| Effort | Ollama | oMLX |
|---|---|---|
Disabled |
think: false |
enable_thinking: false |
Enabled |
think: true |
enable_thinking: true |
Low |
think: "low" |
reasoning_effort: "low" |
Medium |
think: "medium" |
reasoning_effort: "medium" |
High |
think: "high" |
reasoning_effort: "high" |
XHigh |
think: "xhigh" |
reasoning_effort: "xhigh" |
These controls apply to ordinary, streaming, recovery and structured output. Structured JSON remains in content/object; reasoning stays separate.
Explicit model profiles
from mojentic.llm import CompletionConfig, ReasoningEffort, ReasoningProfile
config = CompletionConfig(
reasoning_profile=ReasoningProfile.qwen3_8(),
reasoning_effort=ReasoningEffort.XHigh,
retain_reasoning=True,
)
Qwen3.8 supports exactly Disabled, Low, Medium and XHigh, plus native history.
Enabled and High fail configuration validation for this profile. Omitted effort
remains unspecified. Profiles are chosen by the caller, never inferred from a
model identifier or alias. A custom ReasoningProfile declares name,
supported_efforts and supports_reasoning_history. Unsupported efforts or
retention fail before HTTP. Without a profile the gateway forwards exact controls
and the provider decides model support.
Native history and tool continuation
Gateway responses expose native reasoning in LLMGatewayResponse.thinking.
Assistant history uses LLMMessage.thinking; visible text stays in content,
with tool calls and results in their own fields. Ollama serializes assistant
reasoning as thinking; oMLX serializes it as reasoning_content.
Broker retention is off by default. Pass retain_reasoning=True to generate
or generate_stream to attach completed tool-turn reasoning to assistant history
before the next request. Streamed visible output remains text only. Partial,
failed, capped or cancelled turns never supply retained reasoning. Native history
is never reconstructed from visible content. For an outer turn managed by your
application, explicitly copy a completed gateway response's thinking into an
assistant message when desired.
With retention enabled oMLX requests
chat_template_kwargs: {"preserve_thinking": true}. This records the client
request; forced server settings can override it. Tool identifiers and arguments
remain distinct from reasoning. oMLX carries tool-call identifiers; the Ollama
SDK's tool protocol uses function names and arguments without native call IDs.
Migration from the old effort switch
Earlier Python versions mapped every Ollama level to think: true. Use
ReasoningEffort.Enabled for that boolean behavior. Named levels now send their
exact strings. Qwen3.8 callers should choose its explicit profile and a supported
level rather than Enabled. Ollama ordinary tool arguments now retain JSON types,
and assistant history includes every tool call in its original order.
OpenAI retains existing Low/Medium/High handling and model parameter adaptation.
It rejects Disabled, Enabled, XHigh, explicit profiles, retention and native
assistant history with ValueError; it does not accept the oMLX extension.
Existing temperature/token defaults and deprecated individual keyword arguments
are unchanged by this reasoning correction. Metadata/request fidelity is separate
3.0.0 work.
Local tests execute native-reasoning-v1 through public gateway HTTP and broker
continuations. External consumers and live model servers have not verified this
set. See CONFORMANCE-3.0.0.md for identities, commands and remaining verification;
the coordinated publication hold remains.