Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ you want isn't here, that's a good issue to open.

- **Open models, hosted:** `deepseek` (the default), `openrouter`,
`huggingface` (Inference Providers), `moonshot` (Kimi), `zai` (GLM),
`minimax`, `volcengine` (Ark), `nvidia-nim`, `together`, `fireworks`,
`minimax` / `minimax-anthropic`, `volcengine` (Ark), `nvidia-nim`, `together`, `fireworks`,
`novita`, `siliconflow` / `siliconflow-CN`, `arcee`, `xiaomi-mimo`,
`openmodel`, `deepinfra`, `stepfun`, `atlascloud`, `qianfan`, `wanjie-ark`, plus a generic
`openai`-compatible route for any gateway.
Expand Down
42 changes: 42 additions & 0 deletions crates/agent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,28 @@ impl Default for ModelRegistry {
supports_tools: true,
supports_reasoning: true,
},
ModelInfo {
id: "MiniMax-M3".to_string(),
provider: ProviderKind::MinimaxAnthropic,
aliases: vec![
"minimax-anthropic".to_string(),
"minimax-anthropic-m3".to_string(),
"minimax-m3".to_string(),
],
supports_tools: true,
supports_reasoning: true,
},
ModelInfo {
id: "MiniMax-M2.7".to_string(),
provider: ProviderKind::MinimaxAnthropic,
aliases: vec![
"minimax-anthropic-m2.7".to_string(),
"minimax-anthropic-m2-7".to_string(),
"minimax-m2.7".to_string(),
],
supports_tools: true,
supports_reasoning: true,
},
ModelInfo {
id: "MiniMax-M2.7-highspeed".to_string(),
provider: ProviderKind::Minimax,
Expand Down Expand Up @@ -1561,6 +1583,7 @@ mod tests {
(ProviderKind::Zai, "GLM-5.2"),
(ProviderKind::Stepfun, "step-3.7-flash"),
(ProviderKind::Minimax, "MiniMax-M2.1"),
(ProviderKind::MinimaxAnthropic, "MiniMax-M3"),
(ProviderKind::Openmodel, "deepseek-v4-flash"),
(ProviderKind::Meta, "muse-spark-1.1"),
(ProviderKind::Xai, "grok-4.5"),
Expand Down Expand Up @@ -1661,6 +1684,25 @@ mod tests {
}
}

#[test]
fn minimax_anthropic_models_resolve_when_provider_hinted() {
let registry = ModelRegistry::default();

for (alias, expected) in [
("minimax-anthropic", "MiniMax-M3"),
("minimax-m3", "MiniMax-M3"),
("minimax-m2.7", "MiniMax-M2.7"),
] {
let resolved = registry.resolve(Some(alias), Some(ProviderKind::MinimaxAnthropic));

assert_eq!(resolved.resolved.provider, ProviderKind::MinimaxAnthropic);
assert_eq!(resolved.resolved.id, expected);
assert!(!resolved.used_fallback);
assert!(resolved.resolved.supports_tools);
assert!(resolved.resolved.supports_reasoning);
}
}

#[test]
fn deepseek_v4_flash_alias_resolves_to_openrouter_when_provider_hinted() {
let registry = ModelRegistry::default();
Expand Down
9 changes: 9 additions & 0 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ enum ProviderArg {
Zai,
Stepfun,
Minimax,
#[value(
alias = "minimax_anthropic",
alias = "mini-max-anthropic",
alias = "mini_max_anthropic"
)]
MinimaxAnthropic,
#[value(alias = "deep-infra", alias = "deep_infra")]
Deepinfra,
#[value(alias = "fugu", alias = "sakana-ai", alias = "sakana_ai")]
Expand Down Expand Up @@ -107,6 +113,7 @@ impl From<ProviderArg> for ProviderKind {
ProviderArg::Zai => ProviderKind::Zai,
ProviderArg::Stepfun => ProviderKind::Stepfun,
ProviderArg::Minimax => ProviderKind::Minimax,
ProviderArg::MinimaxAnthropic => ProviderKind::MinimaxAnthropic,
ProviderArg::Deepinfra => ProviderKind::Deepinfra,
ProviderArg::Sakana => ProviderKind::Sakana,
ProviderArg::LongCat => ProviderKind::LongCat,
Expand Down Expand Up @@ -4336,6 +4343,8 @@ mod tests {
("zai", ProviderArg::Zai),
("stepfun", ProviderArg::Stepfun),
("minimax", ProviderArg::Minimax),
("minimax-anthropic", ProviderArg::MinimaxAnthropic),
("minimax_anthropic", ProviderArg::MinimaxAnthropic),
("deepinfra", ProviderArg::Deepinfra),
("deep-infra", ProviderArg::Deepinfra),
("siliconflow-cn", ProviderArg::SiliconflowCn),
Expand Down
29 changes: 25 additions & 4 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ pub struct ProvidersToml {
alias = "minimax"
)]
pub minimax: ProviderConfigToml,
#[serde(
default,
skip_serializing_if = "ProviderConfigToml::is_empty",
alias = "minimax-anthropic",
alias = "minimaxAnthropic",
alias = "mini-max-anthropic",
alias = "mini_max_anthropic"
)]
pub minimax_anthropic: ProviderConfigToml,
#[serde(
default,
skip_serializing_if = "ProviderConfigToml::is_empty",
Expand Down Expand Up @@ -369,6 +378,7 @@ impl ProvidersToml {
ProviderKind::Zai => &self.zai,
ProviderKind::Stepfun => &self.stepfun,
ProviderKind::Minimax => &self.minimax,
ProviderKind::MinimaxAnthropic => &self.minimax_anthropic,
ProviderKind::Deepinfra => &self.deepinfra,
ProviderKind::Sakana => &self.sakana,
ProviderKind::LongCat => &self.longcat,
Expand Down Expand Up @@ -407,6 +417,7 @@ impl ProvidersToml {
ProviderKind::Zai => &mut self.zai,
ProviderKind::Stepfun => &mut self.stepfun,
ProviderKind::Minimax => &mut self.minimax,
ProviderKind::MinimaxAnthropic => &mut self.minimax_anthropic,
ProviderKind::Deepinfra => &mut self.deepinfra,
ProviderKind::Sakana => &mut self.sakana,
ProviderKind::LongCat => &mut self.longcat,
Expand Down Expand Up @@ -2260,6 +2271,7 @@ impl ConfigToml {
ProviderKind::Zai => DEFAULT_ZAI_BASE_URL.to_string(),
ProviderKind::Stepfun => DEFAULT_STEPFUN_BASE_URL.to_string(),
ProviderKind::Minimax => DEFAULT_MINIMAX_BASE_URL.to_string(),
ProviderKind::MinimaxAnthropic => DEFAULT_MINIMAX_ANTHROPIC_BASE_URL.to_string(),
ProviderKind::Deepinfra => DEFAULT_DEEPINFRA_BASE_URL.to_string(),
ProviderKind::Sakana => DEFAULT_SAKANA_BASE_URL.to_string(),
ProviderKind::LongCat => DEFAULT_LONGCAT_BASE_URL.to_string(),
Expand Down Expand Up @@ -2495,8 +2507,10 @@ fn normalize_model_for_provider(provider: ProviderKind, model: &str) -> String {
{
return canonical.to_string();
}
if matches!(provider, ProviderKind::Minimax)
&& let Some(canonical) = canonical_minimax_model_id(model)
if matches!(
provider,
ProviderKind::Minimax | ProviderKind::MinimaxAnthropic
) && let Some(canonical) = canonical_minimax_model_id(model)
{
return canonical.to_string();
}
Expand All @@ -2515,6 +2529,7 @@ fn normalize_model_for_provider(provider: ProviderKind, model: &str) -> String {
| ProviderKind::Zai
| ProviderKind::Stepfun
| ProviderKind::Minimax
| ProviderKind::MinimaxAnthropic
| ProviderKind::Qianfan
| ProviderKind::Ollama
| ProviderKind::Meta
Expand Down Expand Up @@ -2840,7 +2855,7 @@ fn default_model_for_provider(provider: ProviderKind) -> &'static str {
ProviderKind::Openmodel => DEFAULT_OPENMODEL_MODEL,
ProviderKind::Zai => DEFAULT_ZAI_MODEL,
ProviderKind::Stepfun => DEFAULT_STEPFUN_MODEL,
ProviderKind::Minimax => DEFAULT_MINIMAX_MODEL,
ProviderKind::Minimax | ProviderKind::MinimaxAnthropic => DEFAULT_MINIMAX_MODEL,
ProviderKind::Deepinfra => DEFAULT_DEEPINFRA_MODEL,
ProviderKind::Sakana => DEFAULT_SAKANA_MODEL,
ProviderKind::LongCat => DEFAULT_LONGCAT_MODEL,
Expand Down Expand Up @@ -2880,6 +2895,7 @@ fn default_base_url_for_provider(provider: ProviderKind) -> &'static str {
ProviderKind::Zai => DEFAULT_ZAI_BASE_URL,
ProviderKind::Stepfun => DEFAULT_STEPFUN_BASE_URL,
ProviderKind::Minimax => DEFAULT_MINIMAX_BASE_URL,
ProviderKind::MinimaxAnthropic => DEFAULT_MINIMAX_ANTHROPIC_BASE_URL,
ProviderKind::Deepinfra => DEFAULT_DEEPINFRA_BASE_URL,
ProviderKind::Sakana => DEFAULT_SAKANA_BASE_URL,
ProviderKind::LongCat => DEFAULT_LONGCAT_BASE_URL,
Expand Down Expand Up @@ -4423,6 +4439,7 @@ struct EnvRuntimeOverrides {
stepfun_base_url: Option<String>,
stepfun_model: Option<String>,
minimax_base_url: Option<String>,
minimax_anthropic_base_url: Option<String>,
minimax_model: Option<String>,
deepinfra_base_url: Option<String>,
deepinfra_model: Option<String>,
Expand Down Expand Up @@ -4657,6 +4674,9 @@ impl EnvRuntimeOverrides {
minimax_base_url: std::env::var("MINIMAX_BASE_URL")
.ok()
.filter(|v| !v.trim().is_empty()),
minimax_anthropic_base_url: std::env::var("MINIMAX_ANTHROPIC_BASE_URL")
.ok()
.filter(|v| !v.trim().is_empty()),
minimax_model: std::env::var("MINIMAX_MODEL")
.ok()
.filter(|v| !v.trim().is_empty()),
Expand Down Expand Up @@ -4749,6 +4769,7 @@ impl EnvRuntimeOverrides {
ProviderKind::Zai => self.zai_base_url.clone(),
ProviderKind::Stepfun => self.stepfun_base_url.clone(),
ProviderKind::Minimax => self.minimax_base_url.clone(),
ProviderKind::MinimaxAnthropic => self.minimax_anthropic_base_url.clone(),
ProviderKind::Deepinfra => self.deepinfra_base_url.clone(),
ProviderKind::Sakana => self.sakana_base_url.clone(),
ProviderKind::LongCat => self.longcat_base_url.clone(),
Expand Down Expand Up @@ -4781,7 +4802,7 @@ impl EnvRuntimeOverrides {
ProviderKind::Openmodel => self.openmodel_model.clone(),
ProviderKind::Zai => self.zai_model.clone(),
ProviderKind::Stepfun => self.stepfun_model.clone(),
ProviderKind::Minimax => self.minimax_model.clone(),
ProviderKind::Minimax | ProviderKind::MinimaxAnthropic => self.minimax_model.clone(),
ProviderKind::Deepinfra => self.deepinfra_model.clone(),
ProviderKind::Sakana => self.sakana_model.clone(),
ProviderKind::LongCat => self.longcat_model.clone(),
Expand Down
71 changes: 59 additions & 12 deletions crates/config/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ use super::{
DEFAULT_DEEPSEEK_BASE_URL, DEFAULT_DEEPSEEK_MODEL, DEFAULT_FIREWORKS_BASE_URL,
DEFAULT_FIREWORKS_MODEL, DEFAULT_HUGGINGFACE_BASE_URL, DEFAULT_HUGGINGFACE_MODEL,
DEFAULT_LONGCAT_BASE_URL, DEFAULT_LONGCAT_MODEL, DEFAULT_META_BASE_URL, DEFAULT_META_MODEL,
DEFAULT_MINIMAX_BASE_URL, DEFAULT_MINIMAX_MODEL, DEFAULT_MOONSHOT_BASE_URL,
DEFAULT_MOONSHOT_MODEL, DEFAULT_NOVITA_BASE_URL, DEFAULT_NOVITA_MODEL,
DEFAULT_NVIDIA_NIM_BASE_URL, DEFAULT_NVIDIA_NIM_MODEL, DEFAULT_OLLAMA_BASE_URL,
DEFAULT_OLLAMA_MODEL, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_CODEX_BASE_URL,
DEFAULT_OPENAI_CODEX_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_OPENMODEL_BASE_URL,
DEFAULT_OPENMODEL_MODEL, DEFAULT_OPENROUTER_BASE_URL, DEFAULT_OPENROUTER_MODEL,
DEFAULT_QIANFAN_BASE_URL, DEFAULT_QIANFAN_MODEL, DEFAULT_SAKANA_BASE_URL, DEFAULT_SAKANA_MODEL,
DEFAULT_SGLANG_BASE_URL, DEFAULT_SGLANG_MODEL, DEFAULT_SILICONFLOW_BASE_URL,
DEFAULT_SILICONFLOW_CN_BASE_URL, DEFAULT_SILICONFLOW_MODEL, DEFAULT_STEPFUN_BASE_URL,
DEFAULT_STEPFUN_MODEL, DEFAULT_TOGETHER_BASE_URL, DEFAULT_TOGETHER_MODEL,
DEFAULT_VLLM_BASE_URL, DEFAULT_VLLM_MODEL, DEFAULT_VOLCENGINE_BASE_URL,
DEFAULT_MINIMAX_ANTHROPIC_BASE_URL, DEFAULT_MINIMAX_BASE_URL, DEFAULT_MINIMAX_MODEL,
DEFAULT_MOONSHOT_BASE_URL, DEFAULT_MOONSHOT_MODEL, DEFAULT_NOVITA_BASE_URL,
DEFAULT_NOVITA_MODEL, DEFAULT_NVIDIA_NIM_BASE_URL, DEFAULT_NVIDIA_NIM_MODEL,
DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL, DEFAULT_OPENAI_BASE_URL,
DEFAULT_OPENAI_CODEX_BASE_URL, DEFAULT_OPENAI_CODEX_MODEL, DEFAULT_OPENAI_MODEL,
DEFAULT_OPENMODEL_BASE_URL, DEFAULT_OPENMODEL_MODEL, DEFAULT_OPENROUTER_BASE_URL,
DEFAULT_OPENROUTER_MODEL, DEFAULT_QIANFAN_BASE_URL, DEFAULT_QIANFAN_MODEL,
DEFAULT_SAKANA_BASE_URL, DEFAULT_SAKANA_MODEL, DEFAULT_SGLANG_BASE_URL, DEFAULT_SGLANG_MODEL,
DEFAULT_SILICONFLOW_BASE_URL, DEFAULT_SILICONFLOW_CN_BASE_URL, DEFAULT_SILICONFLOW_MODEL,
DEFAULT_STEPFUN_BASE_URL, DEFAULT_STEPFUN_MODEL, DEFAULT_TOGETHER_BASE_URL,
DEFAULT_TOGETHER_MODEL, DEFAULT_VLLM_BASE_URL, DEFAULT_VLLM_MODEL, DEFAULT_VOLCENGINE_BASE_URL,
DEFAULT_VOLCENGINE_MODEL, DEFAULT_WANJIE_ARK_BASE_URL, DEFAULT_WANJIE_ARK_MODEL,
DEFAULT_XAI_BASE_URL, DEFAULT_XAI_MODEL, DEFAULT_XIAOMI_MIMO_BASE_URL,
DEFAULT_XIAOMI_MIMO_MODEL, DEFAULT_ZAI_BASE_URL, DEFAULT_ZAI_MODEL, ProviderKind,
Expand Down Expand Up @@ -581,6 +581,51 @@ provider!(
aliases: ["mini-max", "mini_max"]
);

/// MiniMax route that speaks the Anthropic Messages wire protocol.
pub struct MinimaxAnthropic;

impl Provider for MinimaxAnthropic {
fn id(&self) -> &'static str {
"minimax-anthropic"
}

fn kind(&self) -> ProviderKind {
ProviderKind::MinimaxAnthropic
}

fn display_name(&self) -> &'static str {
"MiniMax (Anthropic-compatible)"
}

fn default_base_url(&self) -> &'static str {
DEFAULT_MINIMAX_ANTHROPIC_BASE_URL
}

fn default_model(&self) -> &'static str {
DEFAULT_MINIMAX_MODEL
}

fn env_vars(&self) -> &'static [&'static str] {
&["MINIMAX_API_KEY"]
}

fn provider_config_key(&self) -> &'static str {
"minimax_anthropic"
}

fn aliases(&self) -> &'static [&'static str] {
&[
"minimax_anthropic",
"mini-max-anthropic",
"mini_max_anthropic",
]
}

fn wire(&self) -> WireFormat {
WireFormat::AnthropicMessages
}
}

provider!(
Deepinfra,
Deepinfra,
Expand Down Expand Up @@ -728,14 +773,15 @@ static OPENMODEL: Openmodel = Openmodel;
static ZAI: Zai = Zai;
static STEPFUN: Stepfun = Stepfun;
static MINIMAX: Minimax = Minimax;
static MINIMAX_ANTHROPIC: MinimaxAnthropic = MinimaxAnthropic;
static DEEPINFRA: Deepinfra = Deepinfra;
static SAKANA: Sakana = Sakana;
static LONGCAT: LongCat = LongCat;
static META: Meta = Meta;
static XAI: Xai = Xai;
static CUSTOM: Custom = Custom;

static PROVIDER_REGISTRY: [&dyn Provider; 33] = [
static PROVIDER_REGISTRY: [&dyn Provider; 34] = [
&DEEPSEEK,
&DEEPSEEK_ANTHROPIC,
&NVIDIA_NIM,
Expand Down Expand Up @@ -763,6 +809,7 @@ static PROVIDER_REGISTRY: [&dyn Provider; 33] = [
&ZAI,
&STEPFUN,
&MINIMAX,
&MINIMAX_ANTHROPIC,
&DEEPINFRA,
&SAKANA,
&LONGCAT,
Expand Down
1 change: 1 addition & 0 deletions crates/config/src/provider_defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ pub(crate) const MINIMAX_M2_1_MODEL: &str = "MiniMax-M2.1";
pub(crate) const MINIMAX_M2_1_HIGHSPEED_MODEL: &str = "MiniMax-M2.1-highspeed";
pub(crate) const MINIMAX_M2_MODEL: &str = "MiniMax-M2";
pub(crate) const DEFAULT_MINIMAX_BASE_URL: &str = "https://api.minimax.io/v1";
pub(crate) const DEFAULT_MINIMAX_ANTHROPIC_BASE_URL: &str = "https://api.minimax.io/anthropic";
pub(crate) const DEFAULT_DEEPINFRA_MODEL: &str = "deepseek-ai/DeepSeek-V4-Pro";
pub(crate) const DEFAULT_DEEPINFRA_FLASH_MODEL: &str = "deepseek-ai/DeepSeek-V4-Flash";
pub(crate) const DEFAULT_DEEPINFRA_BASE_URL: &str = "https://api.deepinfra.com/v1/openai";
Expand Down
9 changes: 8 additions & 1 deletion crates/config/src/provider_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ pub enum ProviderKind {
Stepfun,
#[serde(alias = "mini-max", alias = "mini_max", alias = "minimax")]
Minimax,
#[serde(
alias = "minimax_anthropic",
alias = "mini-max-anthropic",
alias = "mini_max_anthropic"
)]
MinimaxAnthropic,
#[serde(alias = "deep-infra", alias = "deep_infra")]
Deepinfra,
#[serde(alias = "sakana-ai", alias = "sakana_ai", alias = "fugu")]
Expand Down Expand Up @@ -127,7 +133,7 @@ pub enum ProviderKind {
}

impl ProviderKind {
pub const ALL: [Self; 33] = [
pub const ALL: [Self; 34] = [
Self::Deepseek,
Self::DeepseekAnthropic,
Self::NvidiaNim,
Expand Down Expand Up @@ -155,6 +161,7 @@ impl ProviderKind {
Self::Zai,
Self::Stepfun,
Self::Minimax,
Self::MinimaxAnthropic,
Self::Deepinfra,
Self::Sakana,
Self::LongCat,
Expand Down
Loading