From 34c6f93496244c4e4e0f7898f938b64d10a40537 Mon Sep 17 00:00:00 2001 From: Hafiy Zakaria Date: Tue, 28 Apr 2026 20:02:18 +0800 Subject: [PATCH] fix: resolve model.aliases from config.yaml in /model alias resolution hermes config set model.aliases.xxx commands write to the model.aliases nested key, but _load_direct_aliases() only read from the top-level model_aliases key. This meant aliases set via hermes config set were invisible to the /model command, and unrecognised inputs fell through to the DeepSeek normaliser which mapped everything to deepseek-chat. Add a second pass in _load_direct_aliases() that reads model.aliases and converts string-value entries (provider/model format) into DirectAlias objects. The provider is parsed from the slash prefix; if no slash, the current default provider from config is used. Also prevent simple aliases from overriding explicit model_aliases dict entries when both exist. --- hermes_cli/model_switch.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index c7edca0a07..8c2dc2eaed 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -190,11 +190,18 @@ def _load_direct_aliases() -> dict[str, DirectAlias]: model: "minimax-m2.7" provider: custom base_url: "https://ollama.com/v1" + + Also reads ``model.aliases`` (set by ``hermes config set model.aliases.xxx``) + and converts simple string entries (``ds-flash: deepseek/deepseek-v4-flash``) + into DirectAlias objects. The provider is parsed from the ``provider/`` + prefix in the value; if no slash, the current provider is used. """ merged = dict(_BUILTIN_DIRECT_ALIASES) try: from hermes_cli.config import load_config cfg = load_config() + + # --- model_aliases (dict-based format) --- user_aliases = cfg.get("model_aliases") if isinstance(user_aliases, dict): for name, entry in user_aliases.items(): @@ -207,6 +214,30 @@ def _load_direct_aliases() -> dict[str, DirectAlias]: merged[name.strip().lower()] = DirectAlias( model=model, provider=provider, base_url=base_url, ) + + # --- model.aliases (string-based format, from config set) --- + model_section = cfg.get("model", {}) + if isinstance(model_section, dict): + simple_aliases = model_section.get("aliases") + if isinstance(simple_aliases, dict): + current_provider = model_section.get("provider", "") + for name, value in simple_aliases.items(): + if not isinstance(value, str) or not value.strip(): + continue + key = name.strip().lower() + if key in merged: + continue # don't override explicit model_aliases entries + val = value.strip() + if "/" in val: + provider, model = val.split("/", 1) + else: + provider = current_provider + model = val + merged[key] = DirectAlias( + model=model.strip(), + provider=provider.strip() or current_provider, + base_url="", + ) except Exception: pass return merged