@@ -795,8 +795,9 @@ pub fn set_model_config(model: &HermesModelConfig) -> Result<HermesWriteOutcome,
795795/// still have a runnable configuration (Hermes will surface a clear error
796796/// if the default no longer belongs to the active provider).
797797///
798- /// Existing fields in `model:` (`context_length` / `max_tokens` / `base_url`
799- /// / `extra`) are preserved via struct-update.
798+ /// `model.base_url` is updated from the new provider's `settings_config` if
799+ /// present, keeping it in sync with the active provider. Other fields
800+ /// (`context_length` / `max_tokens` / `extra`) are preserved via struct-update.
800801pub fn apply_switch_defaults (
801802 provider_id : & str ,
802803 settings_config : & serde_json:: Value ,
@@ -810,10 +811,18 @@ pub fn apply_switch_defaults(
810811 . map ( |s| s. trim ( ) . to_string ( ) )
811812 . filter ( |s| !s. is_empty ( ) ) ;
812813
814+ // Extract base_url from new provider's settings if present.
815+ let base_url = settings_config
816+ . get ( "base_url" )
817+ . and_then ( |v| v. as_str ( ) )
818+ . map ( |s| s. trim ( ) . to_string ( ) )
819+ . filter ( |s| !s. is_empty ( ) ) ;
820+
813821 let current = get_model_config ( ) ?. unwrap_or_default ( ) ;
814822 let merged = HermesModelConfig {
815823 default : first_model_id. or ( current. default . clone ( ) ) ,
816824 provider : Some ( provider_id. to_string ( ) ) ,
825+ base_url : base_url. or ( current. base_url . clone ( ) ) ,
817826 ..current
818827 } ;
819828 set_model_config ( & merged)
@@ -1747,7 +1756,7 @@ custom_providers:
17471756 let model = get_model_config ( ) . unwrap ( ) . unwrap ( ) ;
17481757 assert_eq ! ( model. default . as_deref( ) , Some ( "new-model" ) ) ;
17491758 assert_eq ! ( model. provider. as_deref( ) , Some ( "new-provider" ) ) ;
1750- // User-customized fields must survive the switch .
1759+ // User-customized fields survive when settings has no base_url .
17511760 assert_eq ! (
17521761 model. base_url. as_deref( ) ,
17531762 Some ( "https://user-override.example.com" )
@@ -1757,6 +1766,37 @@ custom_providers:
17571766 } ) ;
17581767 }
17591768
1769+ #[ test]
1770+ #[ serial]
1771+ fn apply_switch_defaults_updates_base_url_from_settings ( ) {
1772+ with_test_home ( || {
1773+ // Seed an existing model section with a previous base_url.
1774+ let initial = HermesModelConfig {
1775+ default : Some ( "old-model" . to_string ( ) ) ,
1776+ provider : Some ( "old-provider" . to_string ( ) ) ,
1777+ base_url : Some ( "https://old.example.com" . to_string ( ) ) ,
1778+ ..Default :: default ( )
1779+ } ;
1780+ set_model_config ( & initial) . unwrap ( ) ;
1781+
1782+ // New provider's settings include base_url — it should be applied.
1783+ let settings = serde_json:: json!( {
1784+ "base_url" : "https://new.example.com/v1" ,
1785+ "models" : [ { "id" : "new-model" } ]
1786+ } ) ;
1787+ apply_switch_defaults ( "new-provider" , & settings) . unwrap ( ) ;
1788+
1789+ let model = get_model_config ( ) . unwrap ( ) . unwrap ( ) ;
1790+ assert_eq ! ( model. default . as_deref( ) , Some ( "new-model" ) ) ;
1791+ assert_eq ! ( model. provider. as_deref( ) , Some ( "new-provider" ) ) ;
1792+ // base_url from settings_config should override the old one.
1793+ assert_eq ! (
1794+ model. base_url. as_deref( ) ,
1795+ Some ( "https://new.example.com/v1" )
1796+ ) ;
1797+ } ) ;
1798+ }
1799+
17601800 #[ test]
17611801 #[ serial]
17621802 fn apply_switch_defaults_updates_provider_even_without_models ( ) {
0 commit comments