From 0d7b4f947d553ea9ea2d123d3633de9aa2f602e0 Mon Sep 17 00:00:00 2001 From: zhuermu Date: Mon, 3 Aug 2026 10:01:00 +0800 Subject: [PATCH] fix(image-gen): handle stale OpenRouter model defaults --- hermes_cli/tools_config.py | 2 +- plugins/image_gen/openrouter/__init__.py | 4 +++- tests/hermes_cli/test_tools_config.py | 20 +++++++++++++++++++ .../test_openrouter_compat_provider.py | 11 ++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/hermes_cli/tools_config.py b/hermes_cli/tools_config.py index 7be692fcad69..4382b7c024d1 100644 --- a/hermes_cli/tools_config.py +++ b/hermes_cli/tools_config.py @@ -3780,7 +3780,7 @@ def _configure_imagegen_model_for_plugin(plugin_name: str, config: dict) -> None config["image_gen"] = cur_cfg current_model = cur_cfg.get("model") or default_model if current_model not in catalog: - current_model = default_model + current_model = default_model if default_model in catalog else next(iter(catalog)) model_ids = list(catalog.keys()) ordered = [current_model] + [m for m in model_ids if m != current_model] diff --git a/plugins/image_gen/openrouter/__init__.py b/plugins/image_gen/openrouter/__init__.py index a5c6c164da60..15417737b263 100644 --- a/plugins/image_gen/openrouter/__init__.py +++ b/plugins/image_gen/openrouter/__init__.py @@ -243,7 +243,9 @@ def list_models(self) -> List[Dict[str, Any]]: ] def default_model(self) -> Optional[str]: - return self._resolve_model() + # This is the catalog default, not the effective runtime model. + # Runtime overrides are resolved separately by _resolve_model_chain(). + return DEFAULT_MODEL def get_setup_schema(self) -> Dict[str, Any]: return dict(self._setup_schema) diff --git a/tests/hermes_cli/test_tools_config.py b/tests/hermes_cli/test_tools_config.py index 09af0c4e117a..2dc70cb17da7 100644 --- a/tests/hermes_cli/test_tools_config.py +++ b/tests/hermes_cli/test_tools_config.py @@ -423,6 +423,26 @@ def test_picker_repairs_corrupt_config_section(self): assert isinstance(config["image_gen"], dict) assert config["image_gen"]["model"] == "fal-ai/flux-2/klein/9b" + def test_plugin_picker_falls_back_when_default_is_missing_from_catalog(self): + """A stale cross-provider model must not become an unindexable row.""" + from hermes_cli.tools_config import _configure_imagegen_model_for_plugin + + catalog = { + "openai/gpt-5.4-image-2": {"strengths": "quality"}, + "google/gemini-3-pro-image": {"strengths": "fallback"}, + } + config = {"image_gen": {"model": "gpt-image-2-medium"}} + with ( + patch( + "hermes_cli.tools_config._plugin_image_gen_catalog", + return_value=(catalog, "also-missing"), + ), + patch("hermes_cli.tools_config._prompt_choice", return_value=0), + ): + _configure_imagegen_model_for_plugin("openrouter", config) + + assert config["image_gen"]["model"] == "openai/gpt-5.4-image-2" + diff --git a/tests/plugins/image_gen/test_openrouter_compat_provider.py b/tests/plugins/image_gen/test_openrouter_compat_provider.py index 18af8728f966..5429ddba42de 100644 --- a/tests/plugins/image_gen/test_openrouter_compat_provider.py +++ b/tests/plugins/image_gen/test_openrouter_compat_provider.py @@ -95,6 +95,17 @@ def test_default_model(self): # Default must be an image-output model id (provider/model form). assert "/" in DEFAULT_MODEL and "image" in DEFAULT_MODEL + def test_default_model_ignores_runtime_overrides(self, monkeypatch): + """Catalog defaults must not inherit another provider's saved model.""" + from plugins.image_gen.openrouter import DEFAULT_MODEL + + monkeypatch.setenv("OPENROUTER_IMAGE_MODEL", "custom/provider-image-model") + stale = {"model": "gpt-image-2-medium"} + with patch("plugins.image_gen.openrouter._load_image_gen_config", return_value=stale): + provider = _openrouter() + assert provider.default_model() == DEFAULT_MODEL + assert provider._resolve_model() == "custom/provider-image-model" + def test_model_env_override(self, monkeypatch): monkeypatch.setenv("OPENROUTER_IMAGE_MODEL", "black-forest-labs/flux.2-pro")