agent: OpenCode model updates (+6 Go, +7/-1 Zen, removed Free) (#61199)

Closes https://github.com/zed-industries/zed/issues/62559
Related discussion:
https://github.com/zed-industries/zed/discussions/61160

# Objective

Adding newly-released OpenCode models. Removing OpenCode Free models
completely.

## Solution

> [!TIP]
> This pull request is **best reviewed commit-by-commit**!

**OpenCode Go**:
- added **Kimi K3** as per
[[1]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/providers/opencode-go/models/kimi-k3.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/dev/models/moonshotai/kimi-k3.toml).
Currently, the only supported reasoning level available is `Max` which
was validated both with Models.dev data and OpenCode CLI.
- added **Grok 4.5** as per
[[1]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/providers/opencode-go/models/grok-4.5.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/models/xai/grok-4.5.toml)
- added **Tencent Hy3** as per
[[1]](https://github.com/anomalyco/models.dev/commit/b013d94872bb5993fad19ad35fadf74cb029516e)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/tencent/hy3.toml)
- added **GPT 5.6 Luna** as per
[[1]](https://github.com/anomalyco/opencode/pull/39812) and
[[2]](https://github.com/anomalyco/models.dev/blob/dev/providers/opencode-go/models/gpt-5.6-luna.toml)
- added **Qwen 3.8 Max** as per
[[1]](https://github.com/anomalyco/models.dev/commit/403a7bdd43ac7daeadc8bb755eccabf66a0afb9d)
and
[[2]](https://github.com/anomalyco/opencode/commit/e9e747245681127c9f3e300aa8c46f2554fdb294)
- added **GLM 5.3** as per
[[1]](https://github.com/anomalyco/models.dev/blob/3876740bf4f0290e014bc85340e1dba34f0e99a7/models/zhipuai/glm-5.3.toml)
and
[[2]](https://github.com/anomalyco/models.dev/commit/94a1629610b579fd80f7c488f5e4e8d78c8b6883)
and [[3]](https://github.com/anomalyco/opencode/pull/42518)

**OpenCode Zen**:
- added **Gemini 3.5 Flash Lite** as per
[[1]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/providers/opencode/models/gemini-3.5-flash-lite.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/google/gemini-3.5-flash-lite.toml)
- added **Gemini 3.6 Flash** as per
[[1]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/providers/opencode/models/gemini-3.6-flash.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/google/gemini-3.6-flash.toml)
- added **Gemini 3.7 Flash** as per
[[1]](https://github.com/anomalyco/models.dev/pull/4632) and
[[2]](https://github.com/anomalyco/models.dev/commit/b1810e30d7abb11af1092b51aa28cbafc2c440b8)
and [[3]](https://github.com/anomalyco/opencode/pull/42390) and
[[4]](https://github.com/anomalyco/opencode/pull/42393)
- added **Claude Opus 5** as per
[[1]](https://github.com/anomalyco/models.dev/commit/e3ae24cdd7fb524d73e1569ed1713991c5ba688c)
and
[[2]](https://github.com/anomalyco/models.dev/commit/342b5572a06735d0efa8c3c419589051199459d8)
- added **Kimi K3** as per
[[1]](https://github.com/anomalyco/opencode/commit/a9bebd36530dbab28c4644eb7b35b2b1460b8b90)
and
[[2]](https://github.com/anomalyco/models.dev/commit/38ccccc20d7d827f99d791d07cc4cedb8b4eec24)
- added **Grok 4.6** as per
[[1]](https://github.com/anomalyco/models.dev/commit/74789f5a02746cf6c40b75c342432a9d525c28b9)
and
[[2]](https://github.com/anomalyco/opencode/commit/d92d1e654bd1aa8ccb972b3059825314c1633eb8)
and [[3]](https://github.com/anomalyco/models.dev/pull/4575)
- added **Muse Spark 1.2** as per
[[1]](https://github.com/anomalyco/models.dev/commit/fa03dca90bad225a09263ad6ad227c7f47d0172d)
and
[[2]](https://github.com/anomalyco/models.dev/blob/3876740bf4f0290e014bc85340e1dba34f0e99a7/models/meta/muse-spark-1.2.toml)
and [[3]](https://github.com/anomalyco/opencode/pull/42508)
- removed **Claude Opus 4.1** as per
[[1]](https://github.com/anomalyco/models.dev/commit/6951484e985fe55646a741ccd3ca1d4b15008e3f)

**OpenCode Free**: removed all the models and the whole concept of
"OpenCode Free" from Zed. As confirmed [by an Anomaly employee on the
OpenCode
Discord](https://discord.com/channels/1391832426048651334/1394667004979445931/1537530485356363899),
free models are now OpenCode-only since they got abused waaaaay too much
by people. Testing shows that even with an active OpenCode Go
subscription configured, I can't use Free models in Zed — both Big
Pickle and DeepSeek V4 Flash Free failed to reply to a _"hello"_ message
and instead returned a rate-limit error.
A full removal of OpenCode Free from Zed was implemented in
https://github.com/zed-industries/zed/pull/61199/changes/49acbf7c92414c14c453113eb9b886f9bedff7cb
as there was no point in keeping a _"Show free models"_ toggle that
would confuse users.
Users that had `show_free_models` configures in Zed settings will get an
`Property show_free_models is not allowed.` notice. Users that had any
Custom OpenCode models with `"subscription": "free"` configured will get
an `Value is not accepted. Valid values: "zen", "go".` notice. Neither
are blocking errors.

## Testing

✅ Kimi K3 on OpenCode Go - happily confirmed Kimi K3 works by running a
simple "_rename this variable for me. add a function. delete the
function_" test.

✅ Grok 4.5 on OpenCode Go - bravely resisted the continuous and
relentless waves of disgust and confirmed Grok 4.5 works by running a
simple "_rename this variable for me. add a function. delete the
function_" test. I was a bit surprised this worked as I was located in
an EU country while testing this.

✅ Hy3 on OpenCode Go - happily confirmed Hy3 works by running a simple
"_rename this variable for me. add a function. delete the function_"
test.

✅ GPT 5.6 Luna on OpeCode Go - confirmed GPT 5.6 Luna works on OpenCode
Go by running a simple "_rename this variable for me. add a function.
delete the function_" test.

✅ Qwen 3.8 Max on OpeCode Go - confirmed Qwen 3.8 Max works on OpenCode
Go by running a simple "_rename this variable for me. add a function.
delete the function_" test.

✅ GLM 5.3 on OpeCode Go - confirmed GLM 5.3 works on OpenCode Go by
running a simple "_rename this variable for me. add a function. delete
the function_" test.


🤷 I did not test the new OpenCode Zen models (Claude Opus 5, Gemini 3.5
Flash Lite, Gemini 3.6 Flash, Kimi K3, Grok 4.6, Gemini 3.7 Flash, and
Muse Spark 1.2) as I don't have a Zen subscription and I am stubbornly
refusing to get one.

✅ Confirmed removal of OpenCode Free does not impact the rest of the
OpenCode. Confirmed that any Free-related settings generate notices and
not errors. Confirmed the OpenCode tab in Setting looks good.

## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
<summary>Screenshots of the OpenCode Free deprecation warnings</summary>

**Notice shown in the corner of Zed**:
<img width="345" height="90" alt="Notice banner shown in Zed"
src="https://github.com/user-attachments/assets/3e65ba96-582c-424e-9335-1b43d6c632a8"
/>

**Notice shown in Settings -> LLM Providers -> OpenCode**:
<img width="421" height="323" alt="Settings screen showing unexpected
values"
src="https://github.com/user-attachments/assets/a5eb6005-8576-4311-8b23-9c5baf314d8d"
/>

**Notice shown in `settings.json`**:
<img width="569" height="231" alt="Notices shown in settings.json"
src="https://github.com/user-attachments/assets/475375a1-268c-4420-8ef7-a896548e4498"
/>

</details>

---

Release Notes:

- Removed OpenCode Free models from Zed's built-in OpenCode provider
because they are only available through OpenCode surfaces, such as its
external agent through ACP.
- Added Kimi K3, Grok 4.5, Hy3, GPT 5.6 Luna, Qwen 3.8 Max, and GLM 5.3
to OpenCode Go.
- Added Claude Opus 5, Gemini 3.5 Flash Lite, Gemini 3.6 Flash, Gemini
3.7 Flash, Kimi K3, Grok 4.6, and Muse Spark 1.2 to OpenCode Zen.
- Removed the deprecated Claude Opus 4.1 model from OpenCode Zen.

----

> [!TIP]
> This pull request is **best reviewed commit-by-commit**!

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
This commit is contained in:
Vlad Ionescuanddino authored and GitHub committed 2026-08-19 11:07:38 +00:00
1 parent 942b9b9803
commit 29acba32d5
5 files changed
+162 -119

No files matched your search

@@ -72,7 +72,6 @@ pub struct OpenCodeSettings {
pub custom_headers: CustomHeaders,
pub show_zen_models: bool,
pub show_go_models: bool,
pub show_free_models: bool,
}
pub struct OpenCodeLanguageModelProvider {
@@ -167,7 +166,6 @@ impl OpenCodeLanguageModelProvider {
match subscription {
OpenCodeSubscription::Zen => settings.show_zen_models,
OpenCodeSubscription::Go => settings.show_go_models,
OpenCodeSubscription::Free => settings.show_free_models,
}
}
@@ -210,13 +208,6 @@ impl LanguageModelProvider for OpenCodeLanguageModelProvider {
)
} else if Self::subscription_enabled(OpenCodeSubscription::Zen, cx) {
Some(self.create_language_model(opencode::Model::default(), OpenCodeSubscription::Zen))
} else if Self::subscription_enabled(OpenCodeSubscription::Free, cx) {
Some(
self.create_language_model(
opencode::Model::default_free(),
OpenCodeSubscription::Free,
),
)
} else {
None
}
@@ -236,11 +227,6 @@ impl LanguageModelProvider for OpenCodeLanguageModelProvider {
OpenCodeSubscription::Zen,
),
)
} else if Self::subscription_enabled(OpenCodeSubscription::Free, cx) {
Some(self.create_language_model(
opencode::Model::default_free_fast(),
OpenCodeSubscription::Free,
))
} else {
None
}
@@ -273,7 +259,6 @@ impl LanguageModelProvider for OpenCodeLanguageModelProvider {
};
let subscription = match model.subscription {
Some(settings::OpenCodeModelSubscription::Go) => OpenCodeSubscription::Go,
Some(settings::OpenCodeModelSubscription::Free) => OpenCodeSubscription::Free,
Some(settings::OpenCodeModelSubscription::Zen) | None => OpenCodeSubscription::Zen,
};
if !Self::subscription_enabled(subscription, cx) {
@@ -858,7 +843,6 @@ impl ConfigurationView {
match subscription {
OpenCodeSubscription::Zen => opencode_settings.show_zen_models = Some(is_enabled),
OpenCodeSubscription::Go => opencode_settings.show_go_models = Some(is_enabled),
OpenCodeSubscription::Free => opencode_settings.show_free_models = Some(is_enabled),
}
});
}
@@ -935,7 +919,6 @@ impl Render for ConfigurationView {
let settings = OpenCodeLanguageModelProvider::settings(cx);
let show_zen = settings.show_zen_models;
let show_go = settings.show_go_models;
let show_free = settings.show_free_models;
let subscription_toggles = v_flex()
.gap_2()
@@ -943,7 +926,7 @@ impl Render for ConfigurationView {
.child(
Switch::new("opencode-show-zen-models", show_zen.into())
.full_width(true)
.label("Show Zen Models")
.label("Show Zen models")
.label_position(SwitchLabelPosition::Start)
.on_click(cx.listener(|this, state, window, cx| {
this.set_subscription_enabled(
@@ -968,24 +951,9 @@ impl Render for ConfigurationView {
cx,
);
})),
)
.child(Divider::horizontal_dashed())
.child(
Switch::new("opencode-show-free-models", show_free.into())
.full_width(true)
.label("Show Free models")
.label_position(SwitchLabelPosition::Start)
.on_click(cx.listener(|this, state, window, cx| {
this.set_subscription_enabled(
OpenCodeSubscription::Free,
matches!(state, ToggleState::Selected),
window,
cx,
);
})),
);
let no_subscriptions_warning = if !show_zen && !show_go && !show_free {
let no_subscriptions_warning = if !show_zen && !show_go {
Some(Banner::new().severity(Severity::Warning).child(Label::new(
"No subscriptions enabled. Enable at least one subscription to use OpenCode.",
)))
-1
View File
@@ -158,7 +158,6 @@ impl settings::Settings for AllLanguageModelSettings {
),
show_zen_models: opencode.show_zen_models.unwrap_or(true),
show_go_models: opencode.show_go_models.unwrap_or(true),
show_free_models: opencode.show_free_models.unwrap_or(true),
},
open_router: OpenRouterSettings {
api_url: open_router.api_url.unwrap(),
+151 -72
View File
@@ -26,7 +26,6 @@ pub enum ApiProtocol {
pub enum OpenCodeSubscription {
Zen,
Go,
Free,
}
impl OpenCodeSubscription {
@@ -34,7 +33,6 @@ impl OpenCodeSubscription {
match self {
Self::Zen => "Zen",
Self::Go => "Go",
Self::Free => "Free",
}
}
@@ -42,13 +40,12 @@ impl OpenCodeSubscription {
match self {
Self::Zen => "zen",
Self::Go => "go",
Self::Free => "free",
}
}
pub fn api_path_suffix(&self) -> &'static str {
match self {
Self::Zen | Self::Free => "",
Self::Zen => "",
Self::Go => "/go",
}
}
@@ -58,6 +55,8 @@ impl OpenCodeSubscription {
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, EnumIter)]
pub enum Model {
// -- Anthropic protocol models --
#[serde(rename = "claude-opus-5")]
ClaudeOpus5,
#[serde(rename = "claude-opus-4-8")]
ClaudeOpus4_8,
#[serde(rename = "claude-opus-4-7")]
@@ -66,8 +65,6 @@ pub enum Model {
ClaudeOpus4_6,
#[serde(rename = "claude-opus-4-5")]
ClaudeOpus4_5,
#[serde(rename = "claude-opus-4-1")]
ClaudeOpus4_1,
#[default]
#[serde(rename = "claude-sonnet-4-6")]
ClaudeSonnet4_6,
@@ -129,8 +126,14 @@ pub enum Model {
Gemini3_1Pro,
#[serde(rename = "gemini-3-flash")]
Gemini3Flash,
#[serde(rename = "gemini-3.5-flash-lite")]
Gemini3_5FlashLite,
#[serde(rename = "gemini-3.5-flash")]
Gemini3_5Flash,
#[serde(rename = "gemini-3.6-flash")]
Gemini3_6Flash,
#[serde(rename = "gemini-3.7-flash")]
Gemini3_7Flash,
// -- OpenAI Chat Completions protocol models --
#[serde(rename = "deepseek-v4-pro")]
@@ -145,16 +148,24 @@ pub enum Model {
Glm5_1,
#[serde(rename = "glm-5.2")]
Glm5_2,
#[serde(rename = "glm-5.3")]
Glm5_3,
#[serde(rename = "grok-build-0.1")]
GrokBuild0_1,
#[serde(rename = "grok-4.5")]
Grok4_5,
#[serde(rename = "grok-4.6")]
Grok4_6,
#[serde(rename = "muse-spark-1.2")]
MuseSpark1_2,
#[serde(rename = "kimi-k2.5")]
KimiK2_5,
#[serde(rename = "kimi-k2.6")]
KimiK2_6,
#[serde(rename = "kimi-k2.7-code")]
KimiK2_7Code,
#[serde(rename = "kimi-k3")]
KimiK3,
#[serde(rename = "minimax-m2.7")]
MiniMaxM2_7,
#[serde(rename = "minimax-m3")]
@@ -163,10 +174,6 @@ pub enum Model {
MimoV2_5Pro,
#[serde(rename = "mimo-v2.5")]
MimoV2_5,
#[serde(rename = "big-pickle")]
BigPickle,
#[serde(rename = "nemotron-3-ultra-free")]
Nemotron3UltraFree,
#[serde(rename = "qwen3.5-plus")]
Qwen3_5Plus,
#[serde(rename = "qwen3.6-plus")]
@@ -175,6 +182,10 @@ pub enum Model {
Qwen3_7Plus,
#[serde(rename = "qwen3.7-max")]
Qwen3_7Max,
#[serde(rename = "qwen3.8-max")]
Qwen3_8Max,
#[serde(rename = "hy3")]
Hy3,
// -- Custom model --
#[serde(rename = "custom")]
@@ -203,40 +214,36 @@ impl Model {
Self::MiniMaxM2_7
}
pub fn default_free() -> Self {
Self::BigPickle
}
pub fn default_free_fast() -> Self {
Self::Nemotron3UltraFree
}
pub fn available_subscriptions(&self) -> &'static [OpenCodeSubscription] {
match self {
// Models available in both Zen and Go
Self::Glm5_1
| Self::Glm5_2
| Self::Grok4_5
| Self::KimiK2_6
| Self::KimiK2_7Code
| Self::KimiK3
| Self::MiniMaxM2_7
| Self::MiniMaxM3
| Self::DeepSeekV4Pro
| Self::DeepSeekV4Flash
| Self::Gpt5_6Luna
| Self::Qwen3_6Plus => &[OpenCodeSubscription::Zen, OpenCodeSubscription::Go],
// Go-only models
Self::MimoV2_5Pro | Self::MimoV2_5 | Self::Qwen3_7Plus | Self::Qwen3_7Max => {
&[OpenCodeSubscription::Go]
}
Self::MimoV2_5Pro
| Self::MimoV2_5
| Self::Glm5_3
| Self::Qwen3_7Plus
| Self::Qwen3_7Max
| Self::Qwen3_8Max
| Self::Hy3 => &[OpenCodeSubscription::Go],
// Deprecated on Go (per models.dev); still offered on Zen
Self::Glm5 | Self::KimiK2_5 | Self::MiniMaxM2_5 | Self::Qwen3_5Plus => {
&[OpenCodeSubscription::Zen]
}
// Free models
Self::Nemotron3UltraFree | Self::BigPickle => &[OpenCodeSubscription::Free],
// Custom models get their subscription from settings, not from here
Self::Custom { .. } => &[],
@@ -247,11 +254,11 @@ impl Model {
pub fn id(&self) -> &str {
match self {
Self::ClaudeOpus5 => "claude-opus-5",
Self::ClaudeOpus4_8 => "claude-opus-4-8",
Self::ClaudeOpus4_7 => "claude-opus-4-7",
Self::ClaudeOpus4_6 => "claude-opus-4-6",
Self::ClaudeOpus4_5 => "claude-opus-4-5",
Self::ClaudeOpus4_1 => "claude-opus-4-1",
Self::ClaudeSonnet4_6 => "claude-sonnet-4-6",
Self::ClaudeSonnet4_5 => "claude-sonnet-4-5",
Self::ClaudeSonnet4 => "claude-sonnet-4",
@@ -282,7 +289,10 @@ impl Model {
Self::Gemini3_1Pro => "gemini-3.1-pro",
Self::Gemini3Flash => "gemini-3-flash",
Self::Gemini3_5FlashLite => "gemini-3.5-flash-lite",
Self::Gemini3_5Flash => "gemini-3.5-flash",
Self::Gemini3_6Flash => "gemini-3.6-flash",
Self::Gemini3_7Flash => "gemini-3.7-flash",
Self::DeepSeekV4Pro => "deepseek-v4-pro",
Self::DeepSeekV4Flash => "deepseek-v4-flash",
@@ -290,11 +300,15 @@ impl Model {
Self::Glm5 => "glm-5",
Self::Glm5_1 => "glm-5.1",
Self::Glm5_2 => "glm-5.2",
Self::Glm5_3 => "glm-5.3",
Self::GrokBuild0_1 => "grok-build-0.1",
Self::Grok4_5 => "grok-4.5",
Self::Grok4_6 => "grok-4.6",
Self::MuseSpark1_2 => "muse-spark-1.2",
Self::KimiK2_5 => "kimi-k2.5",
Self::KimiK2_6 => "kimi-k2.6",
Self::KimiK2_7Code => "kimi-k2.7-code",
Self::KimiK3 => "kimi-k3",
Self::MiniMaxM2_7 => "minimax-m2.7",
Self::MiniMaxM3 => "minimax-m3",
Self::MimoV2_5Pro => "mimo-v2.5-pro",
@@ -303,8 +317,8 @@ impl Model {
Self::Qwen3_6Plus => "qwen3.6-plus",
Self::Qwen3_7Plus => "qwen3.7-plus",
Self::Qwen3_7Max => "qwen3.7-max",
Self::BigPickle => "big-pickle",
Self::Nemotron3UltraFree => "nemotron-3-ultra-free",
Self::Qwen3_8Max => "qwen3.8-max",
Self::Hy3 => "hy3",
Self::Custom { name, .. } => name,
}
@@ -312,11 +326,11 @@ impl Model {
pub fn display_name(&self) -> &str {
match self {
Self::ClaudeOpus5 => "Claude Opus 5",
Self::ClaudeOpus4_8 => "Claude Opus 4.8",
Self::ClaudeOpus4_7 => "Claude Opus 4.7",
Self::ClaudeOpus4_6 => "Claude Opus 4.6",
Self::ClaudeOpus4_5 => "Claude Opus 4.5",
Self::ClaudeOpus4_1 => "Claude Opus 4.1",
Self::ClaudeSonnet4_6 => "Claude Sonnet 4.6",
Self::ClaudeSonnet4_5 => "Claude Sonnet 4.5",
Self::ClaudeSonnet4 => "Claude Sonnet 4",
@@ -347,7 +361,10 @@ impl Model {
Self::Gemini3_1Pro => "Gemini 3.1 Pro",
Self::Gemini3Flash => "Gemini 3 Flash",
Self::Gemini3_5FlashLite => "Gemini 3.5 Flash Lite",
Self::Gemini3_5Flash => "Gemini 3.5 Flash",
Self::Gemini3_6Flash => "Gemini 3.6 Flash",
Self::Gemini3_7Flash => "Gemini 3.7 Flash",
Self::DeepSeekV4Pro => "DeepSeek V4 Pro",
Self::DeepSeekV4Flash => "DeepSeek V4 Flash",
@@ -355,11 +372,15 @@ impl Model {
Self::Glm5 => "GLM 5",
Self::Glm5_1 => "GLM 5.1",
Self::Glm5_2 => "GLM 5.2",
Self::Glm5_3 => "GLM 5.3",
Self::GrokBuild0_1 => "Grok Build 0.1",
Self::Grok4_5 => "Grok 4.5",
Self::Grok4_6 => "Grok 4.6",
Self::MuseSpark1_2 => "Muse Spark 1.2",
Self::KimiK2_5 => "Kimi K2.5",
Self::KimiK2_6 => "Kimi K2.6",
Self::KimiK2_7Code => "Kimi K2.7 Code",
Self::KimiK3 => "Kimi K3",
Self::MiniMaxM2_7 => "MiniMax M2.7",
Self::MiniMaxM3 => "MiniMax M3",
Self::MimoV2_5Pro => "MiMo V2.5 Pro",
@@ -368,8 +389,8 @@ impl Model {
Self::Qwen3_6Plus => "Qwen3.6 Plus",
Self::Qwen3_7Plus => "Qwen3.7 Plus",
Self::Qwen3_7Max => "Qwen3.7 Max",
Self::BigPickle => "Big Pickle",
Self::Nemotron3UltraFree => "Nemotron 3 Ultra Free",
Self::Qwen3_8Max => "Qwen3.8 Max",
Self::Hy3 => "Hy3",
Self::Custom {
name, display_name, ..
@@ -390,11 +411,11 @@ impl Model {
}
Self::ClaudeFable5
| Self::ClaudeOpus5
| Self::ClaudeOpus4_8
| Self::ClaudeOpus4_7
| Self::ClaudeOpus4_6
| Self::ClaudeOpus4_5
| Self::ClaudeOpus4_1
| Self::ClaudeSonnet5
| Self::ClaudeSonnet4_6
| Self::ClaudeSonnet4_5
@@ -422,26 +443,35 @@ impl Model {
| Self::Gpt5Codex
| Self::Gpt5Nano => ApiProtocol::OpenAiResponses,
Self::Gemini3_1Pro | Self::Gemini3Flash | Self::Gemini3_5Flash => ApiProtocol::Google,
Self::Gemini3_1Pro
| Self::Gemini3Flash
| Self::Gemini3_5FlashLite
| Self::Gemini3_5Flash
| Self::Gemini3_6Flash
| Self::Gemini3_7Flash => ApiProtocol::Google,
Self::Qwen3_7Max | Self::Qwen3_7Plus | Self::Qwen3_6Plus | Self::Qwen3_5Plus => {
ApiProtocol::Anthropic
}
Self::Qwen3_8Max
| Self::Qwen3_7Max
| Self::Qwen3_7Plus
| Self::Qwen3_6Plus
| Self::Qwen3_5Plus => ApiProtocol::Anthropic,
Self::Glm5
| Self::Glm5_1
| Self::Glm5_2
| Self::Glm5_3
| Self::GrokBuild0_1
| Self::Grok4_5
| Self::KimiK2_5
| Self::KimiK2_6
| Self::KimiK2_7Code
| Self::KimiK3
| Self::MimoV2_5Pro
| Self::MimoV2_5
| Self::DeepSeekV4Pro
| Self::DeepSeekV4Flash
| Self::BigPickle
| Self::Nemotron3UltraFree => ApiProtocol::OpenAiChat,
| Self::Hy3 => ApiProtocol::OpenAiChat,
Self::Grok4_6 | Self::Grok4_5 | Self::MuseSpark1_2 => ApiProtocol::OpenAiResponses,
Self::Custom { protocol, .. } => *protocol,
}
@@ -454,16 +484,16 @@ impl Model {
| Self::KimiK2_5
| Self::KimiK2_6
| Self::KimiK2_7Code
| Self::KimiK3
| Self::MimoV2_5
| Self::MimoV2_5Pro
| Self::Glm5
| Self::Glm5_1
| Self::Glm5_2
| Self::Glm5_3
| Self::MiniMaxM2_5
| Self::MiniMaxM2_7
| Self::MiniMaxM3
| Self::Nemotron3UltraFree
| Self::BigPickle => true,
| Self::MiniMaxM3 => true,
Self::Custom {
interleaved_reasoning,
@@ -477,11 +507,10 @@ impl Model {
pub fn max_token_count(&self, subscription: OpenCodeSubscription) -> u64 {
match self {
// Anthropic models
Self::ClaudeOpus4_8 | Self::ClaudeOpus4_7 => 1_000_000,
Self::ClaudeOpus5 | Self::ClaudeOpus4_8 | Self::ClaudeOpus4_7 => 1_000_000,
Self::ClaudeOpus4_6 | Self::ClaudeSonnet4_6 => 1_000_000,
Self::ClaudeSonnet4_5 => 1_000_000,
Self::ClaudeOpus4_5 | Self::ClaudeHaiku4_5 => 200_000,
Self::ClaudeOpus4_1 => 200_000,
Self::ClaudeSonnet4 => 1_000_000,
Self::ClaudeSonnet5 => 1_000_000,
Self::ClaudeFable5 => 1_000_000,
@@ -500,9 +529,12 @@ impl Model {
Self::Gpt5 | Self::Gpt5Codex | Self::Gpt5Nano => 400_000,
// Google models
Self::Gemini3_1Pro => 1_048_576,
Self::Gemini3Flash => 1_048_576,
Self::Gemini3_5Flash => 1_048_576,
Self::Gemini3_1Pro
| Self::Gemini3Flash
| Self::Gemini3_5FlashLite
| Self::Gemini3_5Flash
| Self::Gemini3_6Flash
| Self::Gemini3_7Flash => 1_048_576,
// OpenAI-compatible models
Self::MiniMaxM2_7 => 204_800,
@@ -521,10 +553,12 @@ impl Model {
204_800
}
}
Self::Glm5_2 => 1_000_000,
Self::Glm5_3 | Self::Glm5_2 => 1_000_000,
Self::KimiK2_6 | Self::KimiK2_5 | Self::KimiK2_7Code => 262_144,
Self::KimiK3 => 1_048_576,
Self::GrokBuild0_1 => 256_000,
Self::Grok4_5 => 500_000,
Self::Grok4_6 | Self::Grok4_5 => 500_000,
Self::MuseSpark1_2 => 1_048_576,
Self::MimoV2_5Pro => 1_048_576,
Self::MimoV2_5 => 1_000_000,
Self::Qwen3_5Plus => 262_144,
@@ -535,9 +569,8 @@ impl Model {
262_144
}
}
Self::Qwen3_7Max | Self::Qwen3_7Plus => 1_000_000,
Self::BigPickle => 200_000,
Self::Nemotron3UltraFree => 1_000_000,
Self::Qwen3_8Max | Self::Qwen3_7Max | Self::Qwen3_7Plus => 1_000_000,
Self::Hy3 => 256_000,
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => 1_000_000,
Self::Custom { max_tokens, .. } => *max_tokens,
@@ -547,13 +580,14 @@ impl Model {
pub fn max_output_tokens(&self, subscription: OpenCodeSubscription) -> Option<u64> {
match self {
// Anthropic models
Self::ClaudeOpus4_8 | Self::ClaudeOpus4_7 | Self::ClaudeOpus4_6 => Some(128_000),
Self::ClaudeOpus5 | Self::ClaudeOpus4_8 | Self::ClaudeOpus4_7 | Self::ClaudeOpus4_6 => {
Some(128_000)
}
Self::ClaudeOpus4_5
| Self::ClaudeSonnet4_6
| Self::ClaudeSonnet4_5
| Self::ClaudeHaiku4_5
| Self::ClaudeSonnet4 => Some(64_000),
Self::ClaudeOpus4_1 => Some(32_000),
Self::ClaudeSonnet5 => Some(128_000),
Self::ClaudeFable5 => Some(128_000),
@@ -580,7 +614,12 @@ impl Model {
| Self::Gpt5Nano => Some(128_000),
// Google models
Self::Gemini3_1Pro | Self::Gemini3Flash | Self::Gemini3_5Flash => Some(65_536),
Self::Gemini3_1Pro
| Self::Gemini3Flash
| Self::Gemini3_5FlashLite
| Self::Gemini3_5Flash
| Self::Gemini3_6Flash
| Self::Gemini3_7Flash => Some(65_536),
// OpenAI-compatible models
Self::MiniMaxM2_7 => Some(131_072),
@@ -605,18 +644,20 @@ impl Model {
Some(131_072)
}
}
Self::Glm5_2 => Some(131_072),
Self::BigPickle => Some(32_000),
Self::Glm5_3 | Self::Glm5_2 => Some(131_072),
Self::KimiK2_6 | Self::KimiK2_5 => Some(65_536),
Self::KimiK2_7Code => Some(262_144),
Self::KimiK3 => Some(131_072),
Self::GrokBuild0_1 => Some(256_000),
Self::Grok4_5 => Some(500_000),
Self::Grok4_6 | Self::Grok4_5 => Some(500_000),
Self::MuseSpark1_2 => Some(131_072),
Self::Qwen3_7Max | Self::Qwen3_7Plus | Self::Qwen3_6Plus | Self::Qwen3_5Plus => {
Some(65_536)
}
Self::Qwen3_8Max => Some(131_072),
Self::DeepSeekV4Pro | Self::DeepSeekV4Flash => Some(384_000),
Self::Nemotron3UltraFree => Some(128_000),
Self::MimoV2_5Pro | Self::MimoV2_5 => Some(128_000),
Self::Hy3 => Some(64_000),
Self::Custom {
max_output_tokens, ..
@@ -631,11 +672,11 @@ impl Model {
pub fn supports_images(&self) -> bool {
match self {
// Anthropic models support images
Self::ClaudeOpus4_8
Self::ClaudeOpus5
| Self::ClaudeOpus4_8
| Self::ClaudeOpus4_7
| Self::ClaudeOpus4_6
| Self::ClaudeOpus4_5
| Self::ClaudeOpus4_1
| Self::ClaudeSonnet4_6
| Self::ClaudeSonnet4_5
| Self::ClaudeSonnet4
@@ -668,18 +709,27 @@ impl Model {
Self::Gpt5_3Spark => false,
// Google models support images
Self::Gemini3_1Pro | Self::Gemini3Flash | Self::Gemini3_5Flash => true,
Self::Gemini3_1Pro
| Self::Gemini3Flash
| Self::Gemini3_5FlashLite
| Self::Gemini3_5Flash
| Self::Gemini3_6Flash
| Self::Gemini3_7Flash => true,
// OpenAI-compatible models with image support
Self::KimiK2_6
| Self::KimiK3
| Self::KimiK2_7Code
| Self::KimiK2_5
| Self::GrokBuild0_1
| Self::Grok4_5
| Self::Grok4_6
| Self::MuseSpark1_2
| Self::MimoV2_5
| Self::Qwen3_5Plus
| Self::Qwen3_6Plus
| Self::Qwen3_7Plus
| Self::Qwen3_8Max
| Self::MiniMaxM3 => true,
// OpenAI-compatible models without image support
@@ -687,13 +737,13 @@ impl Model {
| Self::Glm5
| Self::Glm5_1
| Self::Glm5_2
| Self::Glm5_3
| Self::MiniMaxM2_7
| Self::MimoV2_5Pro
| Self::DeepSeekV4Pro
| Self::DeepSeekV4Flash
| Self::Qwen3_7Max
| Self::BigPickle
| Self::Nemotron3UltraFree => false,
| Self::Hy3 => false,
Self::Custom { protocol, .. } => matches!(
protocol,
@@ -709,6 +759,7 @@ impl Model {
match self {
// Anthropic models
Self::ClaudeFable5
| Self::ClaudeOpus5
| Self::ClaudeOpus4_8
| Self::ClaudeOpus4_7
| Self::ClaudeSonnet5 => Some(vec![
@@ -789,14 +840,17 @@ impl Model {
]),
// Google models
Self::Gemini3Flash | Self::Gemini3_5Flash => Some(vec![
Self::Gemini3Flash
| Self::Gemini3_5FlashLite
| Self::Gemini3_5Flash
| Self::Gemini3_6Flash => Some(vec![
ReasoningEffort::Minimal,
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
]),
Self::Gemini3_1Pro => Some(vec![
Self::Gemini3_7Flash | Self::Gemini3_1Pro => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
@@ -809,16 +863,12 @@ impl Model {
ReasoningEffort::Max,
]),
// Moonshot AI models
Self::KimiK3 => Some(vec![ReasoningEffort::Max]),
// MiniMax models
Self::MiniMaxM3 => Some(vec![ReasoningEffort::None]),
// NVIDIA models
Self::Nemotron3UltraFree => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
]),
// Xiaomi MiMo models
Self::MimoV2_5Pro | Self::MimoV2_5 => Some(vec![
ReasoningEffort::Low,
@@ -829,13 +879,42 @@ impl Model {
// Z AI models
Self::Glm5_2 => Some(vec![ReasoningEffort::High, ReasoningEffort::Max]),
Self::Glm5_3 => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::High,
ReasoningEffort::Max,
]),
// Tencent models
Self::Hy3 => Some(vec![
ReasoningEffort::None,
ReasoningEffort::Low,
ReasoningEffort::High,
]),
// SpaceXAI models
Self::Grok4_6 => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
ReasoningEffort::XHigh,
]),
Self::Grok4_5 => Some(vec![
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
]),
// Meta AI models
Self::MuseSpark1_2 => Some(vec![
ReasoningEffort::Minimal,
ReasoningEffort::Low,
ReasoningEffort::Medium,
ReasoningEffort::High,
ReasoningEffort::XHigh,
]),
Self::Custom {
reasoning_effort_levels,
..
@@ -245,8 +245,6 @@ pub struct OpenCodeSettingsContent {
pub show_zen_models: Option<bool>,
/// Whether to show OpenCode Go models. Defaults to true.
pub show_go_models: Option<bool>,
/// Whether to show OpenCode Free models. Defaults to true.
pub show_free_models: Option<bool>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
@@ -266,7 +264,6 @@ pub enum OpenCodeApiProtocol {
pub enum OpenCodeModelSubscription {
Zen,
Go,
Free,
}
#[with_fallible_options]
@@ -278,7 +275,7 @@ pub struct OpenCodeAvailableModel {
pub max_output_tokens: Option<u64>,
/// The API protocol to use for this model: "anthropic", "openai_responses", "openai_chat", or "google". Defaults to "openai_chat".
pub protocol: Option<OpenCodeApiProtocol>,
/// The subscription for this model: "zen", "go", or "free". Defaults to Zen.
/// The subscription for this model: "zen" or "go". Defaults to Zen.
pub subscription: Option<OpenCodeModelSubscription>,
/// Custom Model API URL to use for this model.
pub custom_model_api_url: Option<String>,
+8 -8
View File
@@ -349,7 +349,10 @@ Use OpenCode API access when you have an OpenCode API key. OpenCode Zen and Go a
Zed does not sign in to OpenCode with OAuth or detect your OpenCode subscription; it uses an OpenCode API key saved in the system keychain or `OPENCODE_API_KEY`.
1. Visit [OpenCode Console](https://opencode.ai/auth) and create an account.
2. Free models are available without payment. To use Zen or Go models, make sure you have enough credits or an active subscription.
2. To use Zen or Go models, make sure you have enough credits or an active
subscription. OpenCode Free models are not available when using OpenCode as a
provider in Zed's Agent. You can use them in Zed by running OpenCode as an
[external agent through ACP](https://zed.dev/acp/agent/opencode).
3. Generate an API key from the API Keys section in the OpenCode Console.
4. Open Agent Settings with {#action agent::OpenSettings} and go to the OpenCode section.
5. Enter your OpenCode API key.
@@ -362,19 +365,16 @@ By default, models from all OpenCode subscription types are shown. You can hide
{
"language_models": {
"opencode": {
"show_zen_models": true,
"show_go_models": false,
"show_free_models": false
"show_zen_models": false,
"show_go_models": true
}
}
}
```
**Note:** Zed only bundles configuration for long-term OpenCode Free models. Free models that are available for a limited time are not included in Zed. To use those models, add a custom OpenCode model with configuration from [the OpenCode website](https://opencode.ai/docs/zen#pricing) and [models.dev](https://github.com/anomalyco/models.dev/tree/dev/providers/opencode/models).
#### Custom OpenCode Models {#opencode-custom-models}
The Zed Agent comes preconfigured with OpenCode models. Add custom OpenCode models when you need newer models, limited-time Free models, or models with custom endpoints.
The Zed Agent comes preconfigured with OpenCode models. Add custom OpenCode models when you need newer models or models with custom endpoints.
Add custom models in your settings file:
@@ -409,7 +409,7 @@ The available configuration options for custom OpenCode models are:
- `protocol` (optional, default `"openai_chat"`): model API protocol, one of `"anthropic"`, `"openai_responses"`, `"openai_chat"`, or `"google"`
- `reasoning_effort_levels` (optional): list of supported reasoning effort levels, such as `["none", "low", "medium", "high", "xhigh", "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"`
- `subscription` (optional): `"zen"` or `"go"`; defaults to `"zen"`
- `custom_model_api_url` (optional): custom API base URL to use instead of the default OpenCode API
Custom OpenCode models are listed in the model dropdown in the Agent Panel.