opencode: Model updates + thinking levels (#54880)

Leftovers after https://github.com/zed-industries/zed/pull/53651

Updated models:
- **Zen**: GPT 5.5 and GPT 5.5 Pro - not tested because I don't have a
Zen subscription and I stubbornly refuse to get one
- **Go**: DeepSeek V4 Pro and DeepSeek V4 Flash - failing due to
https://github.com/anomalyco/opencode/issues/24224
- **Go**: MiMo V2.5 and MiMo V2.5 Pro - tested, confirmed working
- **Free**: Ling 2.6 Flash, [available for "a limited
time"](https://x.com/opencode/status/2046717718028513694) - tested,
confirmed working
- **Free**: Hy3 Preview, [available until May
8](https://x.com/opencode/status/2047328981435756824) - tested,
confirmed working

When testing the new models and comparing with OpenCode CLI, I realized
the
[variants](https://opencode.ai/docs/models/#built-in-variants)/thinking
effort configuration was not supported by the Zed Agent implementation.
I added that for OpenCode Go models, after manually checking what each
model supports in OpenCode. Reasoning levels and everything seems to
work (UI looks good, model works) but I have no idea how to specifically
test reasoning levels without doing a full benchmark 🤷
I did not add the same thing for OpenCode Zen models because I could not
figure out a way to get the supported variants.
@benbrandt let me know if you want me to take this out of this PR and to
keep just the model updates!

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:
- OpenCode: add new models (GPT 5.5, DeepSeek V4, MiMo V2.5, Ling 2.6,
Hy3)
- OpenCode Go: add support for configurable reasoning effort levels

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This commit is contained in:
Vlad IonescuandBen Brandt authored and GitHub committed 2026-04-28 16:00:27 +00:00
1 parent d47e73c1ff
commit 2b0f1fa68c
6 files changed
+201 -19

No files matched your search

+114 -13
View File
@@ -1,6 +1,7 @@
use anyhow::{Result, anyhow};
use futures::{AsyncBufReadExt, AsyncReadExt, StreamExt, io::BufReader, stream::BoxStream};
use http_client::{AsyncBody, HttpClient, Method, Request as HttpRequest};
use language_model_core::ReasoningEffort;
use serde::{Deserialize, Serialize};
use strum::EnumIter;
@@ -76,6 +77,10 @@ pub enum Model {
Claude3_5Haiku,
// -- OpenAI Responses API models --
#[serde(rename = "gpt-5.5")]
Gpt5_5,
#[serde(rename = "gpt-5.5-pro")]
Gpt5_5Pro,
#[serde(rename = "gpt-5.4")]
Gpt5_4,
#[serde(rename = "gpt-5.4-pro")]
@@ -114,6 +119,14 @@ pub enum Model {
Gemini3Flash,
// -- OpenAI Chat Completions protocol models --
#[serde(rename = "deepseek-v4-pro")]
DeepSeekV4Pro,
#[serde(rename = "deepseek-v4-flash")]
DeepSeekV4Flash,
#[serde(rename = "ling-2.6-flash-free")]
Ling2_6FlashFree,
#[serde(rename = "hy3-preview-free")]
Hy3PreviewFree,
#[serde(rename = "minimax-m2.5")]
MiniMaxM2_5,
#[serde(rename = "minimax-m2.5-free")]
@@ -132,6 +145,10 @@ pub enum Model {
MimoV2Pro,
#[serde(rename = "mimo-v2-omni")]
MimoV2Omni,
#[serde(rename = "mimo-v2.5-pro")]
MimoV2_5Pro,
#[serde(rename = "mimo-v2.5")]
MimoV2_5,
#[serde(rename = "big-pickle")]
BigPickle,
#[serde(rename = "nemotron-3-super-free")]
@@ -149,6 +166,7 @@ pub enum Model {
max_tokens: u64,
max_output_tokens: Option<u64>,
protocol: ApiProtocol,
reasoning_effort_levels: Option<Vec<ReasoningEffort>>,
custom_model_api_url: Option<String>,
},
}
@@ -186,12 +204,20 @@ impl Model {
| Self::Qwen3_6Plus => &[OpenCodeSubscription::Zen, OpenCodeSubscription::Go],
// Go-only models
Self::MiniMaxM2_7 | Self::MimoV2Pro | Self::MimoV2Omni => &[OpenCodeSubscription::Go],
Self::MiniMaxM2_7
| Self::MimoV2_5Pro
| Self::MimoV2_5
| Self::MimoV2Pro
| Self::MimoV2Omni
| Self::DeepSeekV4Pro
| Self::DeepSeekV4Flash => &[OpenCodeSubscription::Go],
// Free models
Self::MiniMaxM2_5Free | Self::Nemotron3SuperFree | Self::BigPickle => {
&[OpenCodeSubscription::Free]
}
Self::MiniMaxM2_5Free
| Self::Nemotron3SuperFree
| Self::BigPickle
| Self::Ling2_6FlashFree
| Self::Hy3PreviewFree => &[OpenCodeSubscription::Free],
// Custom models get their subscription from settings, not from here
Self::Custom { .. } => &[],
@@ -213,6 +239,8 @@ impl Model {
Self::ClaudeHaiku4_5 => "claude-haiku-4-5",
Self::Claude3_5Haiku => "claude-3-5-haiku",
Self::Gpt5_5 => "gpt-5.5",
Self::Gpt5_5Pro => "gpt-5.5-pro",
Self::Gpt5_4 => "gpt-5.4",
Self::Gpt5_4Pro => "gpt-5.4-pro",
Self::Gpt5_4Mini => "gpt-5.4-mini",
@@ -232,6 +260,10 @@ impl Model {
Self::Gemini3_1Pro => "gemini-3.1-pro",
Self::Gemini3Flash => "gemini-3-flash",
Self::DeepSeekV4Pro => "deepseek-v4-pro",
Self::DeepSeekV4Flash => "deepseek-v4-flash",
Self::Ling2_6FlashFree => "ling-2.6-flash-free",
Self::Hy3PreviewFree => "hy3-preview-free",
Self::MiniMaxM2_5 => "minimax-m2.5",
Self::MiniMaxM2_5Free => "minimax-m2.5-free",
Self::Glm5 => "glm-5",
@@ -241,6 +273,8 @@ impl Model {
Self::MiniMaxM2_7 => "minimax-m2.7",
Self::MimoV2Pro => "mimo-v2-pro",
Self::MimoV2Omni => "mimo-v2-omni",
Self::MimoV2_5Pro => "mimo-v2.5-pro",
Self::MimoV2_5 => "mimo-v2.5",
Self::Qwen3_5Plus => "qwen3.5-plus",
Self::Qwen3_6Plus => "qwen3.6-plus",
Self::BigPickle => "big-pickle",
@@ -262,6 +296,8 @@ impl Model {
Self::ClaudeHaiku4_5 => "Claude Haiku 4.5",
Self::Claude3_5Haiku => "Claude Haiku 3.5",
Self::Gpt5_5 => "GPT 5.5",
Self::Gpt5_5Pro => "GPT 5.5 Pro",
Self::Gpt5_4 => "GPT 5.4",
Self::Gpt5_4Pro => "GPT 5.4 Pro",
Self::Gpt5_4Mini => "GPT 5.4 Mini",
@@ -281,6 +317,10 @@ impl Model {
Self::Gemini3_1Pro => "Gemini 3.1 Pro",
Self::Gemini3Flash => "Gemini 3 Flash",
Self::DeepSeekV4Pro => "DeepSeek V4 Pro",
Self::DeepSeekV4Flash => "DeepSeek V4 Flash",
Self::Ling2_6FlashFree => "Ling 2.6 Flash Free",
Self::Hy3PreviewFree => "Hy3 Preview Free",
Self::MiniMaxM2_5 => "MiniMax M2.5",
Self::MiniMaxM2_5Free => "MiniMax M2.5 Free",
Self::Glm5 => "GLM 5",
@@ -290,6 +330,8 @@ impl Model {
Self::MiniMaxM2_7 => "MiniMax M2.7",
Self::MimoV2Pro => "MiMo V2 Pro",
Self::MimoV2Omni => "MiMo V2 Omni",
Self::MimoV2_5Pro => "MiMo V2.5 Pro",
Self::MimoV2_5 => "MiMo V2.5",
Self::Qwen3_5Plus => "Qwen3.5 Plus",
Self::Qwen3_6Plus => "Qwen3.6 Plus",
Self::BigPickle => "Big Pickle",
@@ -323,7 +365,9 @@ impl Model {
| Self::ClaudeHaiku4_5
| Self::Claude3_5Haiku => ApiProtocol::Anthropic,
Self::Gpt5_4
Self::Gpt5_5
| Self::Gpt5_5Pro
| Self::Gpt5_4
| Self::Gpt5_4Pro
| Self::Gpt5_4Mini
| Self::Gpt5_4Nano
@@ -341,6 +385,8 @@ impl Model {
Self::Gemini3_1Pro | Self::Gemini3Flash => ApiProtocol::Google,
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => ApiProtocol::Anthropic,
Self::MiniMaxM2_5Free
| Self::Glm5
| Self::Glm5_1
@@ -348,10 +394,14 @@ impl Model {
| Self::KimiK2_6
| Self::MimoV2Pro
| Self::MimoV2Omni
| Self::MimoV2_5Pro
| Self::MimoV2_5
| Self::Qwen3_5Plus
| Self::Qwen3_6Plus
| Self::BigPickle
| Self::Nemotron3SuperFree => ApiProtocol::OpenAiChat,
| Self::Nemotron3SuperFree
| Self::Ling2_6FlashFree
| Self::Hy3PreviewFree => ApiProtocol::OpenAiChat,
Self::Custom { protocol, .. } => *protocol,
}
@@ -369,6 +419,7 @@ impl Model {
Self::Claude3_5Haiku => 200_000,
// OpenAI models
Self::Gpt5_5 | Self::Gpt5_5Pro => 1_050_000,
Self::Gpt5_4 | Self::Gpt5_4Pro => 1_050_000,
Self::Gpt5_4Mini | Self::Gpt5_4Nano => 400_000,
Self::Gpt5_3Codex => 400_000,
@@ -386,13 +437,17 @@ impl Model {
// OpenAI-compatible models
Self::MiniMaxM2_7 => 204_800,
Self::MiniMaxM2_5 | Self::MiniMaxM2_5Free => 204_800,
Self::Glm5 | Self::Glm5_1 => 204_800,
Self::Glm5 | Self::Glm5_1 => 202_725,
Self::KimiK2_6 | Self::KimiK2_5 => 262_144,
Self::MimoV2Pro => 1_048_576,
Self::MimoV2_5Pro | Self::MimoV2Pro => 1_048_576,
Self::MimoV2_5 => 1_000_000,
Self::MimoV2Omni => 262_144,
Self::Qwen3_5Plus | Self::Qwen3_6Plus => 262_144,
Self::BigPickle => 200_000,
Self::Nemotron3SuperFree => 204_800,
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => 1_000_000,
Self::Ling2_6FlashFree => 262_100,
Self::Hy3PreviewFree => 256_000,
Self::Custom { max_tokens, .. } => *max_tokens,
}
@@ -411,7 +466,9 @@ impl Model {
Self::Claude3_5Haiku => Some(8_192),
// OpenAI models
Self::Gpt5_4
Self::Gpt5_5
| Self::Gpt5_5Pro
| Self::Gpt5_4
| Self::Gpt5_4Pro
| Self::Gpt5_4Mini
| Self::Gpt5_4Nano
@@ -430,15 +487,22 @@ impl Model {
// Google models
Self::Gemini3_1Pro | Self::Gemini3Flash => Some(65_536),
// Anthropic-compatible models
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => Some(384_000),
// OpenAI-compatible models
Self::MiniMaxM2_7 => Some(131_072),
Self::MiniMaxM2_5 | Self::MiniMaxM2_5Free => Some(131_072),
Self::Glm5 | Self::Glm5_1 => Some(131_072),
Self::Glm5 | Self::Glm5_1 => Some(32_768),
Self::BigPickle => Some(128_000),
Self::KimiK2_6 | Self::KimiK2_5 => Some(65_536),
Self::Qwen3_5Plus | Self::Qwen3_6Plus => Some(65_536),
Self::Nemotron3SuperFree => Some(128_000),
Self::MimoV2Pro | Self::MimoV2Omni => Some(64_000),
Self::MimoV2_5Pro | Self::MimoV2_5 | Self::MimoV2Pro | Self::MimoV2Omni => {
Some(128_000)
}
Self::Ling2_6FlashFree => Some(32_800),
Self::Hy3PreviewFree => Some(64_000),
Self::Custom {
max_output_tokens, ..
@@ -464,7 +528,9 @@ impl Model {
| Self::Claude3_5Haiku => true,
// OpenAI models support images
Self::Gpt5_4
Self::Gpt5_5
| Self::Gpt5_5Pro
| Self::Gpt5_4
| Self::Gpt5_4Pro
| Self::Gpt5_4Mini
| Self::Gpt5_4Nano
@@ -487,6 +553,7 @@ impl Model {
Self::KimiK2_6
| Self::KimiK2_5
| Self::MimoV2Omni
| Self::MimoV2_5
| Self::Qwen3_5Plus
| Self::Qwen3_6Plus => true,
@@ -497,8 +564,14 @@ impl Model {
| Self::Glm5_1
| Self::MiniMaxM2_7
| Self::MimoV2Pro
| Self::MimoV2_5Pro
| Self::BigPickle
| Self::Nemotron3SuperFree => false,
| Self::Nemotron3SuperFree
| Self::Ling2_6FlashFree
| Self::Hy3PreviewFree => false,
// DeepSeek models (Anthropic protocol) don't support images
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => false,
Self::Custom { protocol, .. } => matches!(
protocol,
@@ -509,6 +582,34 @@ impl Model {
),
}
}
pub fn supported_reasoning_effort_levels(&self) -> Option<Vec<ReasoningEffort>> {
match self {
Self::MimoV2_5Pro
| Self::MimoV2_5
| Self::MimoV2Pro
| Self::MimoV2Omni
| Self::Hy3PreviewFree => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
]),
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
ReasoningEffort::XHigh,
]),
Self::Custom {
reasoning_effort_levels,
..
} => reasoning_effort_levels.clone(),
_ => None,
}
}
}
/// Stream generate content for Google models via OpenCode.