From 1d14c2ba40448fd1af0b1c8e56720aa6bde0bfd9 Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Tue, 12 May 2026 10:04:14 +0000 Subject: [PATCH] fix(config): accept modelPresets root alias Co-authored-by: Cursor --- nanobot/config/schema.py | 5 ++++- tests/config/test_model_presets.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/nanobot/config/schema.py b/nanobot/config/schema.py index 3d1bb9e0a..43936597b 100644 --- a/nanobot/config/schema.py +++ b/nanobot/config/schema.py @@ -274,7 +274,10 @@ class Config(BaseSettings): api: ApiConfig = Field(default_factory=ApiConfig) gateway: GatewayConfig = Field(default_factory=GatewayConfig) tools: ToolsConfig = Field(default_factory=ToolsConfig) - model_presets: dict[str, ModelPresetConfig] = Field(default_factory=dict) + model_presets: dict[str, ModelPresetConfig] = Field( + default_factory=dict, + validation_alias=AliasChoices("modelPresets", "model_presets"), + ) @model_validator(mode="after") def _validate_model_preset(self) -> "Config": diff --git a/tests/config/test_model_presets.py b/tests/config/test_model_presets.py index 581202b7b..b243d6e27 100644 --- a/tests/config/test_model_presets.py +++ b/tests/config/test_model_presets.py @@ -39,6 +39,20 @@ def test_resolve_preset_returns_active_preset() -> None: assert resolved.reasoning_effort == "low" +def test_model_presets_accepts_camel_case_root_key() -> None: + config = Config.model_validate({ + "modelPresets": { + "fast": { + "model": "openai/gpt-4.1", + "provider": "openai", + } + }, + }) + + assert config.model_presets["fast"].model == "openai/gpt-4.1" + assert config.model_presets["fast"].provider == "openai" + + def test_resolve_preset_can_target_named_preset_without_activating() -> None: config = Config.model_validate({ "model_presets": {