use std::collections::HashMap; use kernelx_core::models::ModelConfig; use serde_json::Value; #[test] fn test_merge_configs_merge() { let base = ModelConfig { model_id: None, temperature: Some(0.7), max_tokens: Some(2048), system_prompt: Some("Base prompt".into()), extra: { let mut map = HashMap::new(); map.insert("base_key".into(), Value::String("base_value".into())); map }, }; let override_config = ModelConfig { model_id: None, temperature: Some(0.9), max_tokens: None, system_prompt: Some("Override prompt".into()), extra: { let mut map = HashMap::new(); map.insert( "override_key".into(), Value::String("override_value".into()), ); map }, }; let merged = base.merge(&override_config); assert_eq!(merged.temperature, Some(0.9)); assert_eq!(merged.max_tokens, Some(2048)); assert_eq!(merged.system_prompt, Some("Override prompt".into())); assert!(merged.extra.contains_key("base_key")); assert!(merged.extra.contains_key("override_key")); } #[test] fn test_model_config_defaults() { let config = ModelConfig::default(); assert_eq!(config.temperature, Some(0.6)); assert_eq!(config.max_tokens, Some(200)); assert_eq!( config.system_prompt, Some("You are a truthful automaton.".into()) ); assert!(config.extra.is_empty()); } #[test] fn test_model_config_extra_fields() { let mut config = ModelConfig::default(); config.extra.insert( "top_p".into(), serde_json::Value::Number(serde_json::Number::from_f64(0.9).unwrap()), ); config.extra.insert( "presence_penalty".into(), serde_json::Value::Number(serde_json::Number::from_f64(0.1).unwrap()), ); assert_eq!(config.extra.len(), 2); assert!(config.extra.contains_key("top_p")); assert!(config.extra.contains_key("presence_penalty")); } #[test] fn test_partial_config_merge() { let base = ModelConfig { model_id: None, temperature: Some(0.7), max_tokens: Some(2048), system_prompt: None, extra: HashMap::new(), }; let override_config = ModelConfig { model_id: None, temperature: None, max_tokens: Some(1024), system_prompt: Some("New prompt".into()), extra: HashMap::new(), }; let merged = base.merge(&override_config); assert_eq!(merged.temperature, Some(0.7)); // Keeps base value assert_eq!(merged.max_tokens, Some(1024)); // Takes override value assert_eq!(merged.system_prompt, Some("New prompt".into())); // Takes override value } #[test] fn test_model_config_merge_extra_fields() { let mut base_extra = HashMap::new(); base_extra.insert( "top_p".into(), Value::Number(serde_json::Number::from_f64(0.9).unwrap()), ); let mut override_extra = HashMap::new(); override_extra.insert( "frequency_penalty".into(), Value::Number(serde_json::Number::from_f64(0.1).unwrap()), ); override_extra.insert( "top_p".into(), Value::Number(serde_json::Number::from_f64(0.95).unwrap()), ); let base = ModelConfig { model_id: None, temperature: None, max_tokens: None, system_prompt: None, extra: base_extra, }; let override_config = ModelConfig { model_id: None, temperature: None, max_tokens: None, system_prompt: None, extra: override_extra, }; let merged = base.merge(&override_config); assert_eq!(merged.extra.len(), 2); assert_eq!( merged.extra.get("top_p").unwrap(), &Value::Number(serde_json::Number::from_f64(0.95).unwrap()) ); }