refactor: unify setup wizard provider selection with hermes model

setup_model_provider() had 800+ lines of duplicated provider handling
that reimplemented the same credential prompting, OAuth flows, and model
selection that hermes model already provides via the _model_flow_*
functions.  Every new provider had to be added in both places, and the
two implementations diverged in config persistence (setup.py did raw
YAML writes, _set_model_provider, and _update_config_for_provider
depending on the provider — main.py used its own load/save cycle).

This caused the #4172 bug: _model_flow_custom saved config to disk but
the wizard's final save_config(config) overwrote it with stale values.

Fix: extract the core of cmd_model() into select_provider_and_model()
and have setup_model_provider() call it.  After the call, re-sync the
wizard's config dict from disk.  Deletes ~800 lines of duplicated
provider handling from setup.py.

Also fixes cmd_model() double-AuthError crash on fresh installs with
no API keys configured.
This commit is contained in:
Teknium
2026-03-31 01:04:07 -07:00
committed by GitHub
parent 89d8127772
commit 491e79bca9
4 changed files with 283 additions and 1418 deletions

View File

@@ -829,6 +829,17 @@ def cmd_setup(args):
def cmd_model(args):
"""Select default model — starts with provider selection, then model picker."""
_require_tty("model")
select_provider_and_model()
def select_provider_and_model():
"""Core provider selection + model picking logic.
Shared by ``cmd_model`` (``hermes model``) and the setup wizard
(``setup_model_provider`` in setup.py). Handles the full flow:
provider picker, credential prompting, model selection, and config
persistence.
"""
from hermes_cli.auth import (
resolve_provider, AuthError, format_auth_error,
)
@@ -858,7 +869,10 @@ def cmd_model(args):
except AuthError as exc:
warning = format_auth_error(exc)
print(f"Warning: {warning} Falling back to auto provider detection.")
active = resolve_provider("auto")
try:
active = resolve_provider("auto")
except AuthError:
active = "openrouter" # no provider yet; show full picker
# Detect custom endpoint
if active == "openrouter" and get_env_value("OPENAI_BASE_URL"):