fix: widen metadata-preserve guard to list-of-dicts models form

The dict-form guard from PR #67878 only covered the mapping shape
({model: {context_length: ...}}). The list-of-dicts shape
([{id: model, context_length: ...}]) is also a supported config form
(per _declared_model_ids) and was still being replaced with a flat
list of strings, destroying per-model metadata.

Sibling site for #67841.
This commit is contained in:
kshitij 2026-07-20 11:57:45 +05:30 committed by kshitij
parent 311bacb572
commit 2ae195673e
2 changed files with 45 additions and 2 deletions

View file

@ -134,10 +134,15 @@ def _save_discovered_models_to_config(
continue
existing = entry.get("models")
# Preserve per-model metadata: when ``models`` is a mapping
# (e.g. ``{"model-a": {"context_length": 8192}}``), the user
# has curated metadata per model — do not replace it.
# (e.g. ``{"model-a": {"context_length": 8192}}``) or a list of
# dicts (e.g. ``[{"id": "model-a", "context_length": 8192}]``),
# the user has curated metadata per model — do not replace it.
if isinstance(existing, dict):
continue
if isinstance(existing, list) and any(
isinstance(m, dict) for m in existing
):
continue
# Only update when models are stale — avoids unnecessary
# config writes on every picker open.
if isinstance(existing, list) and existing == model_ids:

View file

@ -1516,3 +1516,41 @@ def test_save_discovered_models_preserves_dict_form(monkeypatch):
assert save_calls == [], (
"Dict-form models must not be replaced with a flat list"
)
def test_save_discovered_models_preserves_list_of_dicts_form(monkeypatch):
"""``_save_discovered_models_to_config`` must not replace a list-of-dicts
``models`` form (per-model metadata via ``[{id: ...}]``) with a flat list
of strings (#67841 sibling site)."""
from hermes_cli.model_switch import _save_discovered_models_to_config
save_calls = []
def fake_save(config):
save_calls.append(dict(config))
monkeypatch.setattr("hermes_cli.config.save_config", fake_save)
monkeypatch.setattr(
"hermes_cli.config.load_config",
lambda: {
"custom_providers": [
{
"name": "my-gateway",
"base_url": "https://gateway.example.com/v1",
"models": [
{"id": "configured-model", "context_length": 8192},
{"id": "other-model", "context_length": 4096},
],
}
]
},
)
# List-of-dicts models must NOT be overwritten by discovered models
_save_discovered_models_to_config(
"https://gateway.example.com/v1",
["configured-model", "discovered-model"],
)
assert save_calls == [], (
"List-of-dicts models must not be replaced with a flat list"
)