diff --git a/crates/language_models/src/provider/opencode.rs b/crates/language_models/src/provider/opencode.rs index 1d77c59f5d..8179713a6a 100644 --- a/crates/language_models/src/provider/opencode.rs +++ b/crates/language_models/src/provider/opencode.rs @@ -602,11 +602,11 @@ impl LanguageModel for OpenCodeLanguageModel { } fn max_token_count(&self) -> u64 { - self.model.max_token_count() + self.model.max_token_count(self.subscription) } fn max_output_tokens(&self) -> Option { - self.model.max_output_tokens() + self.model.max_output_tokens(self.subscription) } fn stream_completion( @@ -646,7 +646,9 @@ impl LanguageModel for OpenCodeLanguageModel { request, self.model.id().to_string(), 1.0, - self.model.max_output_tokens().unwrap_or(8192), + self.model + .max_output_tokens(self.subscription) + .unwrap_or(8192), mode, anthropic::completion::AnthropicPromptCacheMode::Automatic, ); @@ -671,7 +673,7 @@ impl LanguageModel for OpenCodeLanguageModel { self.model.id(), false, false, - self.model.max_output_tokens(), + self.model.max_output_tokens(self.subscription), reasoning_effort, self.model.interleaved_reasoning(), ); @@ -692,7 +694,7 @@ impl LanguageModel for OpenCodeLanguageModel { self.model.id(), false, false, - self.model.max_output_tokens(), + self.model.max_output_tokens(self.subscription), None, supports_none_reasoning_effort, ); diff --git a/crates/opencode/src/opencode.rs b/crates/opencode/src/opencode.rs index 0e235bf716..c4919f1759 100644 --- a/crates/opencode/src/opencode.rs +++ b/crates/opencode/src/opencode.rs @@ -141,8 +141,6 @@ pub enum Model { MimoV2_5, #[serde(rename = "big-pickle")] BigPickle, - #[serde(rename = "ring-2.6-1t-free")] - Ring2_6_1TFree, #[serde(rename = "nemotron-3-super-free")] Nemotron3SuperFree, #[serde(rename = "qwen3.5-plus")] @@ -204,10 +202,9 @@ impl Model { | Self::DeepSeekV4Flash => &[OpenCodeSubscription::Go], // Free models - Self::MiniMaxM2_5Free - | Self::Nemotron3SuperFree - | Self::BigPickle - | Self::Ring2_6_1TFree => &[OpenCodeSubscription::Free], + Self::MiniMaxM2_5Free | Self::Nemotron3SuperFree | Self::BigPickle => { + &[OpenCodeSubscription::Free] + } // Custom models get their subscription from settings, not from here Self::Custom { .. } => &[], @@ -263,7 +260,6 @@ impl Model { Self::Qwen3_5Plus => "qwen3.5-plus", Self::Qwen3_6Plus => "qwen3.6-plus", Self::BigPickle => "big-pickle", - Self::Ring2_6_1TFree => "ring-2.6-1t-free", Self::Nemotron3SuperFree => "nemotron-3-super-free", Self::Custom { name, .. } => name, @@ -316,7 +312,6 @@ impl Model { Self::Qwen3_5Plus => "Qwen3.5 Plus", Self::Qwen3_6Plus => "Qwen3.6 Plus", Self::BigPickle => "Big Pickle", - Self::Ring2_6_1TFree => "Ring 2.6 1T Free", Self::Nemotron3SuperFree => "Nemotron 3 Super Free", Self::Custom { @@ -378,7 +373,6 @@ impl Model { | Self::DeepSeekV4Pro | Self::DeepSeekV4Flash | Self::BigPickle - | Self::Ring2_6_1TFree | Self::Nemotron3SuperFree => ApiProtocol::OpenAiChat, Self::Custom { protocol, .. } => *protocol, @@ -395,8 +389,8 @@ impl Model { | Self::MimoV2_5Pro | Self::Glm5 | Self::Glm5_1 - | Self::BigPickle - | Self::Ring2_6_1TFree => true, + | Self::Nemotron3SuperFree + | Self::BigPickle => true, Self::Custom { interleaved_reasoning, @@ -407,7 +401,7 @@ impl Model { } } - pub fn max_token_count(&self) -> u64 { + pub fn max_token_count(&self, subscription: OpenCodeSubscription) -> u64 { match self { // Anthropic models Self::ClaudeOpus4_7 => 1_000_000, @@ -436,13 +430,18 @@ impl Model { // OpenAI-compatible models Self::MiniMaxM2_7 => 204_800, Self::MiniMaxM2_5 | Self::MiniMaxM2_5Free => 204_800, - Self::Glm5 | Self::Glm5_1 => 202_725, + Self::Glm5 | Self::Glm5_1 => { + if subscription == OpenCodeSubscription::Go { + 202_752 + } else { + 204_800 + } + } Self::KimiK2_6 | Self::KimiK2_5 => 262_144, Self::MimoV2_5Pro => 1_048_576, Self::MimoV2_5 => 1_000_000, Self::Qwen3_5Plus | Self::Qwen3_6Plus => 262_144, Self::BigPickle => 200_000, - Self::Ring2_6_1TFree => 262_000, Self::Nemotron3SuperFree => 204_800, Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => 1_000_000, @@ -450,7 +449,7 @@ impl Model { } } - pub fn max_output_tokens(&self) -> Option { + pub fn max_output_tokens(&self, subscription: OpenCodeSubscription) -> Option { match self { // Anthropic models Self::ClaudeOpus4_7 | Self::ClaudeOpus4_6 => Some(128_000), @@ -485,10 +484,22 @@ impl Model { // OpenAI-compatible models Self::MiniMaxM2_7 => Some(131_072), - Self::MiniMaxM2_5 | Self::MiniMaxM2_5Free => Some(131_072), - Self::Glm5 | Self::Glm5_1 => Some(32_768), + Self::MiniMaxM2_5Free => Some(131_072), + Self::MiniMaxM2_5 => { + if subscription == OpenCodeSubscription::Go { + Some(65_536) + } else { + Some(131_072) + } + } + Self::Glm5 | Self::Glm5_1 => { + if subscription == OpenCodeSubscription::Go { + Some(32_768) + } else { + Some(131_072) + } + } Self::BigPickle => Some(128_000), - Self::Ring2_6_1TFree => Some(66_000), Self::KimiK2_6 | Self::KimiK2_5 => Some(65_536), Self::Qwen3_5Plus | Self::Qwen3_6Plus => Some(65_536), Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => Some(384_000), @@ -525,7 +536,6 @@ impl Model { | Self::Gpt5_4Mini | Self::Gpt5_4Nano | Self::Gpt5_3Codex - | Self::Gpt5_3Spark | Self::Gpt5_2 | Self::Gpt5_2Codex | Self::Gpt5_1 @@ -536,6 +546,9 @@ impl Model { | Self::Gpt5Codex | Self::Gpt5Nano => true, + // OpenAI models without image support + Self::Gpt5_3Spark => false, + // Google models support images Self::Gemini3_1Pro | Self::Gemini3Flash => true, @@ -556,7 +569,6 @@ impl Model { | Self::DeepSeekV4Pro | Self::DeepSeekV4Flash | Self::BigPickle - | Self::Ring2_6_1TFree | Self::Nemotron3SuperFree => false, Self::Custom { protocol, .. } => matches!( @@ -571,7 +583,7 @@ impl Model { pub fn supported_reasoning_effort_levels(&self) -> Option> { match self { - Self::Ring2_6_1TFree | Self::MimoV2_5Pro | Self::MimoV2_5 => Some(vec![ + Self::MimoV2_5Pro | Self::MimoV2_5 => Some(vec![ ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High, diff --git a/docs/src/ai/llm-providers.md b/docs/src/ai/llm-providers.md index 3a8455a327..3c08a960da 100644 --- a/docs/src/ai/llm-providers.md +++ b/docs/src/ai/llm-providers.md @@ -656,6 +656,8 @@ By default, models from all subscription types are shown. Optionally, you can hi } ``` +**Note:** Zed only bundles configuration for long-term OpenCode Free models! Free models that are only available for a limited time are not included in Zed. To use such models, create a Custom Model using the configuration settings published on [the OpenCode website](https://opencode.ai/docs/zen#pricing) and on [models.dev](https://github.com/anomalyco/models.dev/tree/dev/providers/opencode/models). + #### Custom Models {#opencode-custom-models} The Zed agent comes pre-configured with OpenCode models. If you wish to use newer models or models with custom endpoints, you can do so by adding the following to your Zed settings file ([how to edit](../configuring-zed.md#settings-files)):