OpenAI-compatible endpoints
o4 can load custom OpenAI-compatible chat providers from ~/.o4/providers.toml.
These providers use the /chat/completions protocol, but many vendors only
support part of the OpenAI request shape. Use the optional compat block on each
model to avoid sending fields that the provider rejects.
Example
Section titled “Example”[[providers]]id = "xiaomi"name = "Xiaomi MiMo Token Plan"api_key_env = "MIMO_API_KEY"base_url = "https://token-plan-sgp.xiaomimimo.com/v1"
[[providers.models]]id = "MiMo-V2.5-Pro"name = "MiMo V2.5 Pro"reasoning = trueinput = ["text"]context_window = 258000max_tokens = 8192
[providers.models.cost]input = 0.0output = 0.0
[providers.models.compat]supported_parameters = ["stream", "max_tokens", "tools"]supports_reasoning_content = false
[providers.models.compat.reasoning]efforts = ["low", "high"]ultra = falseThen run:
export MIMO_API_KEY="your-token-plan-key"o4 -m xiaomi/MiMo-V2.5-ProCompatibility Fields
Section titled “Compatibility Fields”supported_parameters is an allowlist for optional request fields. When set,
o4 only sends the listed fields from this set:
| Parameter | Effect |
|---|---|
stream / streaming |
Send stream: true |
max_tokens |
Send max_tokens |
temperature |
Send temperature |
tools |
Send OpenAI-style function tools |
tool_choice |
Also enables sending tools |
function_call |
Also enables sending tools |
reasoning_content |
Preserve prior assistant reasoning content |
reasoning |
Also enables prior assistant reasoning content |
You can also use explicit booleans:
[providers.models.compat]supports_streaming = truesupports_max_tokens = truesupports_temperature = falsesupports_tools = truesupports_reasoning_content = falseIf no compatibility fields are configured, o4 keeps the legacy behavior and sends the usual OpenAI-compatible fields.
Reasoning Capabilities
Section titled “Reasoning Capabilities”reasoning = true says the model can reason, but it does not imply that the
provider accepts an effort parameter. Declare the exact ordered subset only
when the endpoint supports it:
[providers.models.compat.reasoning]efforts = ["minimal", "low", "medium", "high", "xhigh", "max"]ultra = falseValid provider efforts are minimal, low, medium, high, xhigh, and
max. ultra is separate because it enables o4 orchestration while sending
the model’s declared max effort. When this metadata is absent, the settings
UI offers only default and o4 omits the effort field instead of guessing from
the model name.