diff --git a/crates/rhema-claw/src/backends.rs b/crates/rhema-claw/src/backends.rs index 5fa25a3..6b0095b 100644 --- a/crates/rhema-claw/src/backends.rs +++ b/crates/rhema-claw/src/backends.rs @@ -17,9 +17,11 @@ //! file, persisted in the settings store, changeable over `/v1/providers` //! — the chart pins nothing. //! -//! The per-kind default models are fallbacks only, in one place here: -//! openrouter's `openrouter/auto` deliberately replaces the old -//! copy-pasted google default — a router deserves its own router id. +//! The per-kind default models are fallbacks only, owned by +//! rhema-config's provider registry (`PROVIDERS`): one table, every +//! frontend. openrouter's `openrouter/auto` deliberately replaces the +//! old copy-pasted google default — a router deserves its own router +//! id — and that decision now lives in the row, not in this crate. use std::collections::BTreeMap; use std::future::Future; @@ -63,22 +65,6 @@ pub enum BackendError { MissingKey(String), } -/// The default model per backend kind, when neither the operator nor the -/// settings store names one. -pub fn default_model_for(kind: &str) -> &'static str { - match kind { - "llama-cpp" => "local", - "anthropic" => "claude-sonnet-4-5", - "openai" => "gpt-5", - "openrouter" => "openrouter/auto", - "deepseek" => "deepseek-chat", - // The Coding Plan's flagship, as Z.ai's own client spells it. - "zai" => "GLM-5.3", - "copilot" => "gpt-4.1", - _ => "gemini-3.8-flash", - } -} - /// The listing of a card-backed backend, boxed for the registry; a /// backend without one (the mock, llama's raw id list) carries `None`. pub type ModelListing = Pin, ProviderError>> + Send>>; @@ -526,7 +512,7 @@ pub fn construct(kind: &str, params: &ProviderParams) -> Result return Err(BackendError::UnknownKind(kind.to_owned())), }; - let default_model = default_model_for(kind).to_owned(); + let default_model = rhema_config::default_model(kind).to_owned(); let provider = Arc::new(provider); Ok(Backend { id: kind.to_owned(), @@ -707,7 +693,7 @@ mod tests { id: kind.to_owned(), kind: kind.to_owned(), provider: Arc::new(Stub), - default_model: default_model_for(kind).to_owned(), + default_model: rhema_config::default_model(kind).to_owned(), list_models: None, } } diff --git a/crates/rhema-claw/src/config.rs b/crates/rhema-claw/src/config.rs index 209f26e..174eb54 100644 --- a/crates/rhema-claw/src/config.rs +++ b/crates/rhema-claw/src/config.rs @@ -289,20 +289,13 @@ impl ClawConfig { } /// The model identifier the handler runs: the config's, or the - /// provider's headless default (the same fallbacks the rhema - /// frontend's one-shot uses). An unknown provider string reads as - /// google here; the binary rejects it when it resolves the backend. + /// provider registry's default. An unknown provider string reads + /// as google here; the binary rejects it when it resolves the + /// backend. pub fn resolved_model(&self) -> String { self.model.clone().unwrap_or_else(|| { - match self.provider.as_deref().unwrap_or("google") { - "llama-cpp" => "local", - "anthropic" => "claude-sonnet-4-5", - "openai" => "gpt-5", - // The Coding Plan's flagship, as Z.ai's own client spells it. - "zai" => "GLM-5.3", - _ => "gemini-3.8-flash", - } - .to_owned() + let provider = self.provider.as_deref().unwrap_or("google"); + rhema_config::default_model(provider).to_owned() }) } @@ -577,6 +570,19 @@ ingest_token: door-key "claude-sonnet-4-5" ); assert_eq!(config(Some("openai"), None).resolved_model(), "gpt-5"); + // The arms the old inline match dropped: the registry answers + // for the whole fleet, so a provider cannot silently read as + // google's default. + assert_eq!( + config(Some("deepseek"), None).resolved_model(), + "deepseek-chat" + ); + assert_eq!(config(Some("copilot"), None).resolved_model(), "gpt-4.1"); + assert_eq!( + config(Some("openrouter"), None).resolved_model(), + "openrouter/auto" + ); + assert_eq!(config(Some("zai"), None).resolved_model(), "GLM-5.3"); // An explicit model always wins, whatever the provider. assert_eq!( config(Some("openrouter"), Some("x/y")).resolved_model(),