use std::collections::HashMap; use std::sync::Arc; use crate::agent::AgentError; use crate::config::{LLMProviderConfig, MemoryMaintenanceConfig}; #[derive(Clone)] pub(crate) struct ProviderConfigService { default_provider_config: LLMProviderConfig, provider_configs: Arc>, maintenance_config: MemoryMaintenanceConfig, } impl ProviderConfigService { pub(crate) fn new( default_provider_config: LLMProviderConfig, provider_configs: HashMap, maintenance_config: MemoryMaintenanceConfig, ) -> Self { Self { default_provider_config, provider_configs: Arc::new(provider_configs), maintenance_config, } } pub(crate) fn select(&self, agent_name: Option<&str>) -> Result { match agent_name.map(str::trim).filter(|value| !value.is_empty()) { None | Some("default") => Ok(self.default_provider_config.clone()), Some(agent_name) => self .provider_configs .get(agent_name) .cloned() .ok_or_else(|| { AgentError::Other(format!("Scheduled agent '{}' not found", agent_name)) }), } } pub(crate) fn default_provider_config(&self) -> LLMProviderConfig { self.default_provider_config.clone() } pub(crate) fn default_maintenance_config(&self) -> MemoryMaintenanceConfig { self.maintenance_config.clone() } } #[cfg(test)] mod tests { use super::*; fn test_provider_config_named(name: &str, model_id: &str) -> LLMProviderConfig { LLMProviderConfig { provider_type: "openai".to_string(), name: name.to_string(), base_url: "http://localhost".to_string(), api_key: "test-key".to_string(), extra_headers: HashMap::new(), llm_timeout_secs: 120, memory_maintenance_timeout_secs: 600, model_id: model_id.to_string(), temperature: Some(0.0), max_tokens: Some(32), context_window_tokens: None, model_extra: HashMap::new(), max_tool_iterations: 1, tool_result_max_chars: 100_000, context_tool_result_trim_chars: 20_000, max_images_in_context: 1, max_image_age_rounds: 10, } } #[test] fn test_select_uses_named_agent_override() { let default_provider = test_provider_config_named("default-provider", "default-model"); let service = ProviderConfigService::new( default_provider, HashMap::from([( "planner".to_string(), test_provider_config_named("planner-provider", "planner-model"), )]), MemoryMaintenanceConfig::default(), ); let selected = service.select(Some("planner")).unwrap(); assert_eq!(selected.name, "planner-provider"); assert_eq!(selected.model_id, "planner-model"); } #[test] fn test_select_falls_back_to_default() { let default_provider = test_provider_config_named("default-provider", "default-model"); let service = ProviderConfigService::new( default_provider, HashMap::new(), MemoryMaintenanceConfig::default(), ); let selected = service.select(Some("default")).unwrap(); assert_eq!(selected.name, "default-provider"); assert_eq!(selected.model_id, "default-model"); } }