diff --git a/crates/language_model_core/src/language_model_core.rs b/crates/language_model_core/src/language_model_core.rs index cb1f75b7fd..26ef0867db 100644 --- a/crates/language_model_core/src/language_model_core.rs +++ b/crates/language_model_core/src/language_model_core.rs @@ -478,15 +478,17 @@ pub enum ReasoningEffort { Medium, High, XHigh, + Max, } impl ReasoningEffort { - pub const OPENAI_COMPATIBLE_SELECTABLE: [Self; 5] = [ + pub const OPENAI_COMPATIBLE_SELECTABLE: [Self; 6] = [ Self::Minimal, Self::Low, Self::Medium, Self::High, Self::XHigh, + Self::Max, ]; pub fn label(self) -> &'static str { @@ -497,6 +499,7 @@ impl ReasoningEffort { Self::Medium => "Medium", Self::High => "High", Self::XHigh => "Extra High", + Self::Max => "Max", } } @@ -508,6 +511,7 @@ impl ReasoningEffort { Self::Medium => "medium", Self::High => "high", Self::XHigh => "xhigh", + Self::Max => "max", } } } diff --git a/crates/language_models/src/provider/open_ai_compatible.rs b/crates/language_models/src/provider/open_ai_compatible.rs index fb914a6f7a..847978b795 100644 --- a/crates/language_models/src/provider/open_ai_compatible.rs +++ b/crates/language_models/src/provider/open_ai_compatible.rs @@ -516,7 +516,7 @@ mod tests { .map(|level| level.value.as_ref()) .collect::>(); - assert_eq!(values, ["minimal", "low", "medium", "high", "xhigh"]); + assert_eq!(values, ["minimal", "low", "medium", "high", "xhigh", "max"]); assert_eq!( effort_levels .iter() diff --git a/crates/language_models/src/provider/openai_subscribed.rs b/crates/language_models/src/provider/openai_subscribed.rs index 3cddb57d7e..f63268e60e 100644 --- a/crates/language_models/src/provider/openai_subscribed.rs +++ b/crates/language_models/src/provider/openai_subscribed.rs @@ -433,6 +433,7 @@ impl LanguageModel for OpenAiSubscribedLanguageModel { ReasoningEffort::Medium => ("Medium", "medium"), ReasoningEffort::High => ("High", "high"), ReasoningEffort::XHigh => ("Extra High", "xhigh"), + ReasoningEffort::Max => return None, // Not supported by any OpenAI models }; Some(LanguageModelEffortLevel { diff --git a/crates/language_models/src/provider/opencode.rs b/crates/language_models/src/provider/opencode.rs index c2ccaad088..9a5dbcdfcc 100644 --- a/crates/language_models/src/provider/opencode.rs +++ b/crates/language_models/src/provider/opencode.rs @@ -38,7 +38,8 @@ fn normalize_reasoning_effort(effort: &str) -> Option { "low" => Some(ReasoningEffort::Low), "medium" => Some(ReasoningEffort::Medium), "high" => Some(ReasoningEffort::High), - "max" | "xhigh" => Some(ReasoningEffort::XHigh), + "xhigh" => Some(ReasoningEffort::XHigh), + "max" => Some(ReasoningEffort::Max), _ => None, } } @@ -51,6 +52,7 @@ fn reasoning_effort_display(effort: ReasoningEffort) -> (&'static str, &'static ReasoningEffort::Medium => ("Medium", "medium"), ReasoningEffort::High => ("High", "high"), ReasoningEffort::XHigh => ("XHigh", "xhigh"), + ReasoningEffort::Max => ("Max", "max"), } } diff --git a/crates/language_models/src/provider/x_ai.rs b/crates/language_models/src/provider/x_ai.rs index 0627874bcc..1d21464c5f 100644 --- a/crates/language_models/src/provider/x_ai.rs +++ b/crates/language_models/src/provider/x_ai.rs @@ -342,6 +342,7 @@ fn supported_thinking_effort_levels(model: &x_ai::Model) -> Vec ("Medium", "medium"), open_ai::ReasoningEffort::High => ("High", "high"), open_ai::ReasoningEffort::XHigh => ("Extra High", "xhigh"), + open_ai::ReasoningEffort::Max => return None, // Not supported by any xAI models }; Some(LanguageModelEffortLevel { diff --git a/crates/open_ai/src/open_ai.rs b/crates/open_ai/src/open_ai.rs index e706e10a0e..ec25a80d7e 100644 --- a/crates/open_ai/src/open_ai.rs +++ b/crates/open_ai/src/open_ai.rs @@ -260,6 +260,7 @@ impl Model { ReasoningEffort::Medium => &[ReasoningEffort::Medium], ReasoningEffort::High => &[ReasoningEffort::High], ReasoningEffort::XHigh => &[ReasoningEffort::XHigh], + ReasoningEffort::Max => &[ReasoningEffort::Max], }, Self::O3 => &[ ReasoningEffort::Low, diff --git a/crates/opencode/src/opencode.rs b/crates/opencode/src/opencode.rs index 43a09777ee..ab030721e3 100644 --- a/crates/opencode/src/opencode.rs +++ b/crates/opencode/src/opencode.rs @@ -667,6 +667,7 @@ impl Model { ReasoningEffort::Medium, ReasoningEffort::High, ReasoningEffort::XHigh, + ReasoningEffort::Max, ]), Self::Custom { diff --git a/docs/src/ai/use-api-access.md b/docs/src/ai/use-api-access.md index b7458d4f41..52b2eaf960 100644 --- a/docs/src/ai/use-api-access.md +++ b/docs/src/ai/use-api-access.md @@ -389,7 +389,7 @@ Add custom models in your settings file: "max_tokens": 123456, "max_output_tokens": 98765, "protocol": "openai_chat", - "reasoning_effort_levels": ["low", "medium", "high"], + "reasoning_effort_levels": ["low", "medium", "high", "max"], "interleaved_reasoning": false, "subscription": "go", "custom_model_api_url": "https://example.com/zen" @@ -407,7 +407,7 @@ The available configuration options for custom OpenCode models are: - `max_tokens` (required): maximum model context window size, such as `1000000` - `max_output_tokens` (optional): maximum tokens the model can generate, such as `64000` - `protocol` (required): model API protocol, one of `"anthropic"`, `"openai_responses"`, `"openai_chat"`, or `"google"` -- `reasoning_effort_levels` (optional): list of supported reasoning effort levels, such as `["low", "medium", "high"]`. The last value in the list is used as the default +- `reasoning_effort_levels` (optional): list of supported reasoning effort levels, such as `["low", "medium", "high", "max"]`. The last value in the list is used as the default - `interleaved_reasoning` (optional, default `false`): whether thinking tokens are sent as a dedicated `reasoning_content` field. Applies only when using the `openai_chat` protocol - `subscription` (optional): `"zen"`, `"go"`, or `"free"`; defaults to `"zen"` - `custom_model_api_url` (optional): custom API base URL to use instead of the default OpenCode API @@ -503,7 +503,7 @@ By default, OpenAI-compatible models inherit these capabilities: If a model only works with the Responses API, set `capabilities.chat_completions` to `false`. Zed will use the Responses endpoint for that model. -For reasoning models (e.g. GPT-5), set `reasoning_effort` to the non-`none` effort level your endpoint supports. This enables thinking in the agent panel and tells Zed which effort to send when thinking is enabled. The provider settings UI can configure this when adding an OpenAI-compatible provider. Zed sends OpenAI-style `reasoning_effort` on chat-completions requests. For endpoints that document a maximum effort named `"max"` but also accept or map `"xhigh"` (such as OpenRouter and Z.AI), configure `"xhigh"` in Zed. +For reasoning models (e.g. GPT-5), set `reasoning_effort` to the non-`none` effort level your endpoint supports. This enables thinking in the agent panel and tells Zed which effort to send when thinking is enabled. The provider settings UI can configure this when adding an OpenAI-compatible provider. Zed sends OpenAI-style `reasoning_effort` on chat-completions requests. If the model requires the Responses API for reasoning state, set `capabilities.chat_completions` to `false`: @@ -535,7 +535,7 @@ If the model requires the Responses API for reasoning state, set `capabilities.c } ``` -Valid settings values are `"none"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, and `"xhigh"`. Use `"none"` in `settings.json` when you need to force reasoning off for an endpoint; the provider setup UI exposes the non-`none` values for thinking-capable models. For chat-completions endpoints that should receive prior thinking back in a dedicated `reasoning_content` field, also set `capabilities.interleaved_reasoning` to `true`. If the endpoint expects the output-token limit as `max_tokens` instead of `max_completion_tokens`, set `capabilities.max_tokens_parameter` to `true`. +Valid settings values are `"none"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, and `"max"`. Use `"none"` in `settings.json` when you need to force reasoning off for an endpoint; the provider setup UI exposes the non-`none` values for thinking-capable models. For chat-completions endpoints that should receive prior thinking back in a dedicated `reasoning_content` field, also set `capabilities.interleaved_reasoning` to `true`. If the endpoint expects the output-token limit as `max_tokens` instead of `max_completion_tokens`, set `capabilities.max_tokens_parameter` to `true`. For example, a chat-completions endpoint with the maximum OpenAI-style reasoning effort, streamed thinking, and `max_tokens` output limits can be configured as: @@ -550,7 +550,7 @@ For example, a chat-completions endpoint with the maximum OpenAI-style reasoning "name": "reasoning-model", "max_tokens": 1000000, "max_output_tokens": 128000, - "reasoning_effort": "xhigh", + "reasoning_effort": "max", "capabilities": { "tools": true, "images": false,