Bug Description
When a provider is defined under the top-level providers: dict in config.yaml with a models: key as a YAML list, the models list is silently dropped during normalization. This causes the provider to appear twice in the /model picker — once correctly (from the raw providers: dict, showing the models) and once with 0 models (from the get_compatible_custom_providers() path, which converts it via _normalize_custom_provider_entry()).
Steps to Reproduce
- Add a provider to
config.yaml using the providers: dict format with a list under models::
providers:
apigw2:
api: https://example.com/api/v1
api_key: your-key-here
models:
- model-a
- model-b
- Open the
/model picker.
- Observe
apigw2 appears twice: once with 2 models, once with 0 models.
Root Cause
In hermes_cli/config.py, _normalize_custom_provider_entry() only copies the models field when it is a dict:
# config.py ~line 1690
models = entry.get("models")
if isinstance(models, dict) and models:
normalized["models"] = models
But the providers: dict format uses a plain list for models:. So the list is dropped, producing a normalized entry with no models.
get_compatible_custom_providers() calls providers_dict_to_custom_providers() which calls _normalize_custom_provider_entry() on every providers: dict entry, then merges the result with the existing compatible providers list. The resulting entry for apigw2 has no models key, and deduplication fails because the two entries have different shapes, so both survive into the picker.
Expected Behavior
_normalize_custom_provider_entry() should accept models as either a list or a dict. The provider should appear exactly once in the picker, with all configured models selectable.
Suggested Fix
models = entry.get("models")
if isinstance(models, (list, dict)) and models:
normalized["models"] = models
Environment
- Hermes Agent: latest main (cloned from NousResearch/hermes-agent)
- macOS arm64
- Config format:
providers: dict (not legacy custom_providers: list)
Bug Description
When a provider is defined under the top-level
providers:dict inconfig.yamlwith amodels:key as a YAML list, the models list is silently dropped during normalization. This causes the provider to appear twice in the/modelpicker — once correctly (from the rawproviders:dict, showing the models) and once with 0 models (from theget_compatible_custom_providers()path, which converts it via_normalize_custom_provider_entry()).Steps to Reproduce
config.yamlusing theproviders:dict format with a list undermodels::/modelpicker.apigw2appears twice: once with 2 models, once with 0 models.Root Cause
In
hermes_cli/config.py,_normalize_custom_provider_entry()only copies themodelsfield when it is a dict:But the
providers:dict format uses a plain list formodels:. So the list is dropped, producing a normalized entry with no models.get_compatible_custom_providers()callsproviders_dict_to_custom_providers()which calls_normalize_custom_provider_entry()on everyproviders:dict entry, then merges the result with the existing compatible providers list. The resulting entry forapigw2has nomodelskey, and deduplication fails because the two entries have different shapes, so both survive into the picker.Expected Behavior
_normalize_custom_provider_entry()should acceptmodelsas either a list or a dict. The provider should appear exactly once in the picker, with all configured models selectable.Suggested Fix
Environment
providers:dict (not legacycustom_providers:list)