From 1c76689b2852dd95dc1b10ad534aeda8d6c8d657 Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Thu, 30 Apr 2026 21:36:14 +0800 Subject: [PATCH] fix(agent): resolve supports_vision override for named custom providers Named custom providers are rewritten to provider="custom" at runtime (hermes_cli/runtime_provider.py:_resolve_named_custom_runtime), so a config under providers.my-vllm.models.my-llava.supports_vision was unreachable via self.provider alone. Also try cfg.model.provider as a candidate provider key, covering both runtime and config naming. Adds a regression test for the named-provider path. --- run_agent.py | 12 ++++++++++-- .../run_agent/test_vision_aware_preprocessing.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/run_agent.py b/run_agent.py index d76894cf05b..34d591e59a8 100644 --- a/run_agent.py +++ b/run_agent.py @@ -3213,8 +3213,16 @@ class AIAgent: cfg = load_config() provider = (getattr(self, "provider", "") or "").strip() model = (getattr(self, "model", "") or "").strip() - for keys in (("model", "supports_vision"), - ("providers", provider, "models", model, "supports_vision")): + # self.provider is the runtime-resolved value, which is rewritten + # to "custom" for named custom providers (see + # hermes_cli/runtime_provider.py:_resolve_named_custom_runtime), + # while the config still holds the user-declared name (e.g. + # "my-vllm") under model.provider. Try both as provider keys. + config_provider = str(cfg_get(cfg, "model", "provider") or "").strip() + candidates = [("model", "supports_vision")] + for p in dict.fromkeys(filter(None, (provider, config_provider))): + candidates.append(("providers", p, "models", model, "supports_vision")) + for keys in candidates: override = cfg_get(cfg, *keys) if override is not None: return bool(override) diff --git a/tests/run_agent/test_vision_aware_preprocessing.py b/tests/run_agent/test_vision_aware_preprocessing.py index 08fe6502e96..056754862cc 100644 --- a/tests/run_agent/test_vision_aware_preprocessing.py +++ b/tests/run_agent/test_vision_aware_preprocessing.py @@ -186,6 +186,21 @@ class TestModelSupportsVision: patch("agent.models_dev.get_model_capabilities", return_value=None): assert agent._model_supports_vision() is True + def test_named_custom_provider_resolved_via_config_provider(self): + # Named custom providers get runtime self.provider rewritten to + # "custom" while the config keeps the original name under + # model.provider. The override must still resolve. + agent = _make_agent() + agent.provider = "custom" + agent.model = "my-llava" + cfg = { + "model": {"provider": "my-vllm", "default": "my-llava"}, + "providers": {"my-vllm": {"models": {"my-llava": {"supports_vision": True}}}}, + } + with patch("hermes_cli.config.load_config", return_value=cfg), \ + patch("agent.models_dev.get_model_capabilities", return_value=None): + assert agent._model_supports_vision() is True + def test_override_false_disables_vision_for_models_dev_models(self): agent = _make_agent() fake_caps = MagicMock()