WebUI model picker doesn't show custom `providers:` entry that uses `key_env` (CLI `hermes model` does)
#6804 aperta il 6 ago 2026
Metriche repository
- Star
- (17.368 stelle)
- Metriche merge PR
- (Merge medio 14h 31m) (314 PR mergiate in 30 g)
Descrizione
Summary
A custom OpenAI-compatible provider configured via the providers: section in config.yaml with key_env (instead of an inline api_key) is invisible in the WebUI model picker, but appears correctly in the CLI hermes model picker. Adding a models: list to the config entry works around it.
Reproduction
config.yaml:
providers:
synthetic:
name: synthetic
base_url: https://api.synthetic.new/openai/v1
key_env: SYNTHETIC_API_KEY
.env:
SYNTHETIC_API_KEY=***
- CLI:
hermes model→ synthetic appears as a picker row with its live model list. ✅ - WebUI: Models page / composer model dropdown → synthetic does not appear. ❌
Root cause (two independent gaps)
1. api/providers.py::_provider_has_key() ignores key_env for providers.<id> entries.
The function checks (in order): known env var from _PROVIDER_ENV_VAR static table → model.api_key (only if active) → providers.<id>.api_key (inline only) → custom_providers[].api_key. It never resolves the key_env field on a providers: entry. So the provider reports has_key: false.
The custom_providers[] legacy list path does resolve ${VAR} env refs in api_key (line ~1148), but the providers: dict path (line ~1305-1310) only reads a bare api_key string — no key_env lookup.
2. api/config.py::get_available_models() only live-probes the active provider.
Non-active providers: entries with no models: list in config get zero models. The final group filter (config.py:~5440) drops any group with no models unless its provider_id starts with custom: or it's a plugin provider. A bare slug like synthetic is neither, so it's dropped.
The CLI path (hermes_cli/model_switch.py::list_authenticated_providers, section 3) probes /v1/models for every providers: entry — which is why the CLI picker works.
Workaround
Add a models: list to the provider entry:
providers:
synthetic:
name: synthetic
base_url: https://api.synthetic.new/openai/v1
key_env: SYNTHETIC_API_KEY
models:
- syn:large:text
- hf:moonshotai/Kimi-K3
# ...
The WebUI reads the configured list without a live probe, so the group surfaces. Confirmed working.
Suggested fix
Gap 1: In _provider_has_key() (api/providers.py), when checking providers.<id>, also resolve key_env → os.environ / .env file, matching what the custom_providers[] path already does for ${VAR} refs.
Gap 2: In get_available_models() (api/config.py), live-probe /v1/models for non-active providers: entries that have a base_url but no models: list — or relax the final group filter to keep providers:-derived groups with zero models (matching how custom:* slugs are kept).
Environment
- Hermes Agent: current
main - Provider: custom OpenAI-compatible endpoint (
https://api.synthetic.new/openai/v1) - Config shape:
providers:dict withkey_env(not legacycustom_providers:list, not inlineapi_key)
Copy-paste ready. The two gaps are independently fixable; gap 1 alone fixes the "invisible provider" symptom, gap 2 fixes the "no models until you hand-list them" symptom.