fix: BYOK/custom provider models missing from WebUI model dropdown (#815)

Closes #815.

Three root causes fixed:

1. Provider aliases (z.ai/x.ai/google/grok/claude/aws-bedrock/dashscope/~25 more) not
   normalized before _PROVIDER_MODELS lookup — provider fell to empty else-branch while
   TUI worked (it normalizes at startup). Fixed via _resolve_provider_alias() + inlined
   _PROVIDER_ALIASES table in api/config.py.

2. Silent ImportError in original normalization: 'from hermes_cli.models import
   _PROVIDER_ALIASES' inside try/except silently failed without hermes-agent on sys.path
   (CI, minimal installs). The inlined table fixes this — normalization now works
   regardless of whether hermes-agent is installed.

3. /api/models/live?provider=custom now falls back to custom_providers entries from
   config.yaml when provider_model_ids() returns empty.

Also: provider_id on every group in /api/models response for deterministic JS optgroup
matching (no substring false positives). 17 targeted tests, 1725/1725 full suite.
This commit is contained in:
nesquena-hermes
2026-04-21 17:24:54 -07:00
committed by GitHub
parent a4d59b9e6c
commit 8f1f582caf
5 changed files with 496 additions and 3 deletions

View File

@@ -90,6 +90,7 @@ async function populateModelDropdown(){
for(const g of data.groups){
const og=document.createElement('optgroup');
og.label=g.provider;
if(g.provider_id) og.dataset.provider=g.provider_id;
for(const m of g.models){
const opt=document.createElement('option');
opt.value=m.id;
@@ -134,6 +135,12 @@ async function _fetchLiveModels(provider, sel){
// Keep other providers' optgroups intact
let providerGroup=null;
for(const og of sel.querySelectorAll('optgroup')){
// Prefer exact data-provider match (set from provider_id in API response)
// over substring label match — avoids false positives like 'zai' not matching
// 'Z.AI / GLM' and vice versa.
if(og.dataset.provider&&og.dataset.provider===provider){
providerGroup=og; break;
}
if(og.label&&og.label.toLowerCase().includes(provider.toLowerCase())){
providerGroup=og; break;
}