Files
zed/crates/language_models/src/settings.rs
T
df11a245bb agent: Add Opencode Zen provider (#49589)
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Per Opencode's website:
> Zen gives you access to a curated set of AI models that OpenCode has
tested and benchmarked specifically for coding agents. No need to worry
about inconsistent performance and quality, use validated models that
work.
> - [x] Testing select models and consulting their teams
> - [x] Working with providers to ensure they're delivered properly
> - [x] Benchmarking all model-provider combinations we recommend

There are so many models available, but only a few work well with coding
agents. Most providers configure them differently with varying results.

The models under the Zen umbrella typically have a more reliable
token(s) per second speed with minimal outages. The opencode ecosystem
has improved my workflow if not many others' !

Release Notes:
- Added [Opencode Zen](https://opencode.ai/zen) to list of providers

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-03-23 12:48:49 +00:00

133 lines
5.8 KiB
Rust

use std::sync::Arc;
use collections::HashMap;
use settings::RegisterSetting;
use crate::provider::{
anthropic::AnthropicSettings, bedrock::AmazonBedrockSettings, cloud::ZedDotDevSettings,
deepseek::DeepSeekSettings, google::GoogleSettings, lmstudio::LmStudioSettings,
mistral::MistralSettings, ollama::OllamaSettings, open_ai::OpenAiSettings,
open_ai_compatible::OpenAiCompatibleSettings, open_router::OpenRouterSettings,
opencode::OpenCodeSettings, vercel::VercelSettings, vercel_ai_gateway::VercelAiGatewaySettings,
x_ai::XAiSettings,
};
#[derive(Debug, RegisterSetting)]
pub struct AllLanguageModelSettings {
pub anthropic: AnthropicSettings,
pub bedrock: AmazonBedrockSettings,
pub deepseek: DeepSeekSettings,
pub google: GoogleSettings,
pub lmstudio: LmStudioSettings,
pub mistral: MistralSettings,
pub ollama: OllamaSettings,
pub opencode: OpenCodeSettings,
pub open_router: OpenRouterSettings,
pub openai: OpenAiSettings,
pub openai_compatible: HashMap<Arc<str>, OpenAiCompatibleSettings>,
pub vercel: VercelSettings,
pub vercel_ai_gateway: VercelAiGatewaySettings,
pub x_ai: XAiSettings,
pub zed_dot_dev: ZedDotDevSettings,
}
impl settings::Settings for AllLanguageModelSettings {
const PRESERVED_KEYS: Option<&'static [&'static str]> = Some(&["version"]);
fn from_settings(content: &settings::SettingsContent) -> Self {
let language_models = content.language_models.clone().unwrap();
let anthropic = language_models.anthropic.unwrap();
let bedrock = language_models.bedrock.unwrap();
let deepseek = language_models.deepseek.unwrap();
let google = language_models.google.unwrap();
let lmstudio = language_models.lmstudio.unwrap();
let mistral = language_models.mistral.unwrap();
let ollama = language_models.ollama.unwrap();
let opencode = language_models.opencode.unwrap();
let open_router = language_models.open_router.unwrap();
let openai = language_models.openai.unwrap();
let openai_compatible = language_models.openai_compatible.unwrap();
let vercel = language_models.vercel.unwrap();
let vercel_ai_gateway = language_models.vercel_ai_gateway.unwrap();
let x_ai = language_models.x_ai.unwrap();
let zed_dot_dev = language_models.zed_dot_dev.unwrap();
Self {
anthropic: AnthropicSettings {
api_url: anthropic.api_url.unwrap(),
available_models: anthropic.available_models.unwrap_or_default(),
},
bedrock: AmazonBedrockSettings {
available_models: bedrock.available_models.unwrap_or_default(),
region: bedrock.region,
endpoint: bedrock.endpoint_url, // todo(should be api_url)
profile_name: bedrock.profile,
role_arn: None, // todo(was never a setting for this...)
authentication_method: bedrock.authentication_method.map(Into::into),
allow_global: bedrock.allow_global,
allow_extended_context: bedrock.allow_extended_context,
},
deepseek: DeepSeekSettings {
api_url: deepseek.api_url.unwrap(),
available_models: deepseek.available_models.unwrap_or_default(),
},
google: GoogleSettings {
api_url: google.api_url.unwrap(),
available_models: google.available_models.unwrap_or_default(),
},
lmstudio: LmStudioSettings {
api_url: lmstudio.api_url.unwrap(),
available_models: lmstudio.available_models.unwrap_or_default(),
},
mistral: MistralSettings {
api_url: mistral.api_url.unwrap(),
available_models: mistral.available_models.unwrap_or_default(),
},
ollama: OllamaSettings {
api_url: ollama.api_url.unwrap(),
auto_discover: ollama.auto_discover.unwrap_or(true),
available_models: ollama.available_models.unwrap_or_default(),
context_window: ollama.context_window,
},
opencode: OpenCodeSettings {
api_url: opencode.api_url.unwrap(),
available_models: opencode.available_models.unwrap_or_default(),
},
open_router: OpenRouterSettings {
api_url: open_router.api_url.unwrap(),
available_models: open_router.available_models.unwrap_or_default(),
},
openai: OpenAiSettings {
api_url: openai.api_url.unwrap(),
available_models: openai.available_models.unwrap_or_default(),
},
openai_compatible: openai_compatible
.into_iter()
.map(|(key, value)| {
(
key,
OpenAiCompatibleSettings {
api_url: value.api_url,
available_models: value.available_models,
},
)
})
.collect(),
vercel: VercelSettings {
api_url: vercel.api_url.unwrap(),
available_models: vercel.available_models.unwrap_or_default(),
},
vercel_ai_gateway: VercelAiGatewaySettings {
api_url: vercel_ai_gateway.api_url.unwrap(),
available_models: vercel_ai_gateway.available_models.unwrap_or_default(),
},
x_ai: XAiSettings {
api_url: x_ai.api_url.unwrap(),
available_models: x_ai.available_models.unwrap_or_default(),
},
zed_dot_dev: ZedDotDevSettings {
available_models: zed_dot_dev.available_models.unwrap_or_default(),
},
}
}
}