fix(config): respect --force for bare model key overwrite

--force was silently ignored for 'model' keys — the guard always
redirected to model.default even when the user explicitly asked to
replace the entire section. Now --force triggers a warning and
proceeds with the destructive overwrite for model too, matching
the non-model mapping --force behaviour.
This commit is contained in:
Baophan00 2026-07-31 20:05:44 +07:00 committed by Teknium
parent 99cfa8f063
commit a017297cf1
2 changed files with 29 additions and 8 deletions

View File

@ -4866,14 +4866,21 @@ def set_config_value(key: str, value: str, force: bool = False):
_existing = user_config.get(key)
if isinstance(_existing, dict):
if key == "model":
# Redirect bare-model shorthand to model.default while
# keeping every sibling mapping key intact.
key = "model.default"
print(
f"✓ Redirecting bare 'model' to 'model.default' "
f"(preserving {len(_existing)} existing model sub-key(s))"
)
# value was already coerced above; proceed to _set_nested
if force:
# --force: allow destructive section overwrite.
print(
f"⚠ Replacing entire 'model' section with a scalar "
f"(discarding {len(_existing)} existing sub-key(s))"
)
else:
# Redirect bare-model shorthand to model.default while
# keeping every sibling mapping key intact.
key = "model.default"
print(
f"✓ Redirecting bare 'model' to 'model.default' "
f"(preserving {len(_existing)} existing model sub-key(s))"
)
# value was already coerced above; proceed to _set_nested
elif not force:
_sub = [k for k in _existing if isinstance(k, str)]
print(

View File

@ -643,3 +643,17 @@ class TestMappingGuard:
parsed = _yaml.safe_load(_read_config(_isolated_hermes_home))
assert parsed["model"]["default"] == "claude-opus-4"
assert parsed["model"]["provider"] == "openai-api"
def test_model_force_overwrites_entire_section(self, _isolated_hermes_home):
"""hermes config set --force model <id> → overwrite entire section."""
self._write_config(_isolated_hermes_home, {
"model": {
"default": "gpt-4o",
"provider": "openai-api",
"context_length": 128_000,
}
})
set_config_value("model", "claude-opus-4", force=True)
import yaml as _yaml
parsed = _yaml.safe_load(_read_config(_isolated_hermes_home))
assert parsed["model"] == "claude-opus-4"