Problem
hermes model and /model tab completion use completely different data sources, creating a fragmented UX:
| Step |
Current behavior |
Expected behavior |
hermes model |
Writes model.default (single value, overwrites) |
Should append to providers.<slug>.models (list, cumulative) |
/model tab |
Reads hardcoded MODEL_ALIASES + external models.dev catalog |
Should read from providers in config.yaml |
| Model switching |
Overwrites model.default, previously selected models "disappear" |
model.default points into providers, nothing is lost |
Details
-
_save_model_choice() (hermes_cli/auth.py:3815) only writes config["model"]["default"] = model_id. It never touches the providers section.
-
_model_flow_api_key_provider() (hermes_cli/main.py:4489-4501) only writes model["provider"] and model["base_url"]. Again, providers is never updated.
-
Tab completion reads from MODEL_ALIASES (hardcoded dict in hermes_cli/model_switch.py:105-154) and falls back to models.dev catalog. It does not read the user's providers config at all.
-
The providers section in config.yaml (which supports api_key_env, base_url, models) is effectively a second-class citizen — only useful if manually edited.
Proposed Solution
Make providers the single source of truth for model registry:
1. hermes model should write to providers
When a user selects a model through hermes model:
- API key →
.env (already works ✅)
- Base URL →
.env (already works ✅)
- Model entry →
providers.<slug>.models (new — currently only writes model.default)
Example result after running hermes model twice for the same provider:
providers:
deepseek:
api_key_env: DEEPSEEK_API_KEY
base_url: DEEPSEEK_BASE_URL
models:
deepseek-v4-pro:
name: deepseek-v4-pro
provider: deepseek
deepseek-v4-flash:
name: deepseek-v4-flash
provider: deepseek
2. /model tab completion should read from providers
Tab completion should list all models from providers in config.yaml first, then fall back to catalog/aliases for models not yet configured.
3. Keep MODEL_ALIASES as fallback only
The hardcoded aliases are still useful for first-time setup or providers not yet in config.yaml. They should serve as suggestions, not the primary data source.
Benefits
- Unified mental model: "models in
providers are what I can use"
- No lost models: previously selected models accumulate in
providers, not overwritten
- Config portability:
providers + .env fully describes all available models
- Minimal code change: mainly
_save_model_choice() and tab completion data source
Affected Files
hermes_cli/auth.py — _save_model_choice() should also update providers
hermes_cli/main.py — _model_flow_api_key_provider() post-save logic
hermes_cli/model_switch.py — tab completion should read providers first
hermes_cli/model_switch.py — MODEL_ALIASES becomes fallback, not primary
Problem
hermes modeland/modeltab completion use completely different data sources, creating a fragmented UX:hermes modelmodel.default(single value, overwrites)providers.<slug>.models(list, cumulative)/modeltabMODEL_ALIASES+ external models.dev catalogprovidersin config.yamlmodel.default, previously selected models "disappear"model.defaultpoints intoproviders, nothing is lostDetails
_save_model_choice()(hermes_cli/auth.py:3815) only writesconfig["model"]["default"] = model_id. It never touches theproviderssection._model_flow_api_key_provider()(hermes_cli/main.py:4489-4501) only writesmodel["provider"]andmodel["base_url"]. Again,providersis never updated.Tab completion reads from
MODEL_ALIASES(hardcoded dict inhermes_cli/model_switch.py:105-154) and falls back to models.dev catalog. It does not read the user'sprovidersconfig at all.The
providerssection inconfig.yaml(which supportsapi_key_env,base_url,models) is effectively a second-class citizen — only useful if manually edited.Proposed Solution
Make
providersthe single source of truth for model registry:1.
hermes modelshould write toprovidersWhen a user selects a model through
hermes model:.env(already works ✅).env(already works ✅)providers.<slug>.models(new — currently only writesmodel.default)Example result after running
hermes modeltwice for the same provider:2.
/modeltab completion should read fromprovidersTab completion should list all models from
providersin config.yaml first, then fall back to catalog/aliases for models not yet configured.3. Keep
MODEL_ALIASESas fallback onlyThe hardcoded aliases are still useful for first-time setup or providers not yet in config.yaml. They should serve as suggestions, not the primary data source.
Benefits
providersare what I can use"providers, not overwrittenproviders+.envfully describes all available models_save_model_choice()and tab completion data sourceAffected Files
hermes_cli/auth.py—_save_model_choice()should also updateprovidershermes_cli/main.py—_model_flow_api_key_provider()post-save logichermes_cli/model_switch.py— tab completion should readprovidersfirsthermes_cli/model_switch.py—MODEL_ALIASESbecomes fallback, not primary