diff --git a/hermes_cli/main_provider_setup.py b/hermes_cli/main_provider_setup.py index 632377dde8..08f4cad61b 100644 --- a/hermes_cli/main_provider_setup.py +++ b/hermes_cli/main_provider_setup.py @@ -150,32 +150,26 @@ def _save_aux_choice(task: str, *, provider: str, model: str = "", base_url: str def _reset_aux_to_auto() -> int: """Reset every known aux task (built-in + plugin) back to auto/empty. Returns number reset.""" from hermes_cli.config import load_config, save_config - cfg = load_config() - aux = _ensure_dict_section(cfg, "auxiliary") - count = 0 - for task, _name, _desc in _all_aux_tasks(): - entry = _ensure_dict_section(aux, task) + def _clear(entry: dict, auto: str) -> bool: + # Only the routing fields; timeout/download_timeout (aux) and max_concurrent_children + # etc. (delegation) are user-tuned and preserved. *auto* is the reset provider value + # ("auto" for aux tasks, "" for delegation); anything else counts as a change. changed = False - if entry.get("provider") not in {None, "", "auto"}: - entry["provider"] = "auto" + if entry.get("provider") not in {None, "", auto}: + entry["provider"] = auto changed = True for field in ("model", "base_url", "api_key"): if entry.get(field): entry[field] = "" changed = True - # Preserve timeout/download_timeout — those are user-tuned, not routing - if changed: - count += 1 - # Delegation: clear only the routing fields; max_concurrent_children etc. are preserved. + return changed + + cfg = load_config() + aux = _ensure_dict_section(cfg, "auxiliary") + count = sum(_clear(_ensure_dict_section(aux, task), "auto") for task, _name, _desc in _all_aux_tasks()) dele = cfg.get("delegation") if isinstance(dele, dict): - changed = False - for field in ("provider", "model", "base_url", "api_key"): - if dele.get(field): - dele[field] = "" - changed = True - if changed: - count += 1 + count += _clear(dele, "") save_config(cfg) return count @@ -444,7 +438,6 @@ def _save_custom_provider(base_url, api_key="", model="", context_length=None, n providers = cfg.get("custom_providers") or [] if not isinstance(providers, list): providers = [] - for entry in providers: if not (isinstance(entry, dict) and entry.get("base_url", "").rstrip("/") == base_url.rstrip("/")): continue @@ -453,11 +446,7 @@ def _save_custom_provider(base_url, api_key="", model="", context_length=None, n entry["model"] = model changed = True if model and context_length: - models_cfg = entry.get("models", {}) - if not isinstance(models_cfg, dict): - models_cfg = {} - models_cfg[model] = {"context_length": context_length} - entry["models"] = models_cfg + _ensure_dict_section(entry, "models")[model] = {"context_length": context_length} changed = True if api_mode: if entry.get("api_mode") != api_mode: @@ -475,8 +464,7 @@ def _save_custom_provider(base_url, api_key="", model="", context_length=None, n save_config(cfg) return # already saved, updated if needed - if not name: - name = _auto_provider_name(base_url) + name = name or _auto_provider_name(base_url) entry = {"name": name, "base_url": base_url} if key_env: entry["key_env"] = key_env @@ -754,10 +742,7 @@ def _named_custom_provider_map(cfg) -> dict[str, dict[str, str]]: name_lc = str(name or "").strip().lower() pkey_lc = str(provider_key or "").strip().lower() model = str(model or "").strip() - for identity in ((pkey_lc, model), (pkey_lc,), (name_lc, model), (name_lc,)): - if identity[0] and identity in refs: - return refs[identity] - return "" + return next((refs[i] for i in ((pkey_lc, model), (pkey_lc,), (name_lc, model), (name_lc,)) if i[0] and i in refs), "") custom_provider_map = {} for entry in get_compatible_custom_providers(cfg): diff --git a/hermes_cli/model_setup_flows.py b/hermes_cli/model_setup_flows.py index 8282e49963..7632dc0107 100644 --- a/hermes_cli/model_setup_flows.py +++ b/hermes_cli/model_setup_flows.py @@ -308,9 +308,7 @@ def _model_flow_nous(config, current_model="", args=None): # Portal URL is needed for upgrade links and the recommendations endpoints. _nous_portal_url = "" with contextlib.suppress(Exception): - _nous_state = get_provider_auth_state("nous") - if _nous_state: - _nous_portal_url = _nous_state.get("portal_base_url", "") + _nous_portal_url = (get_provider_auth_state("nous") or {}).get("portal_base_url", "") catalog = _nous_model_catalog(free_tier, _nous_portal_url, model_ids, pricing) if catalog is None: @@ -352,8 +350,7 @@ def _model_flow_openai_codex(config, current_model=""): _codex_token = None with contextlib.suppress(Exception): _codex_status = get_codex_auth_status() - if _codex_status.get("logged_in"): - _codex_token = _codex_status.get("api_key") + _codex_token = _codex_status.get("api_key") if _codex_status.get("logged_in") else None if not _codex_token: with contextlib.suppress(Exception): from hermes_cli.auth import resolve_codex_runtime_credentials @@ -401,11 +398,9 @@ def _model_flow_qwen_oauth(_config, current_model=""): from hermes_cli.models import fetch_api_models status = get_qwen_auth_status() if not status.get("logged_in"): - _say("Not logged into Qwen CLI OAuth.", "Run: qwen auth qwen-oauth") - if status.get("auth_file"): - print(f"Expected credentials file: {status.get('auth_file')}") - if status.get("error"): - print(f"Error: {status.get('error')}") + _say("Not logged into Qwen CLI OAuth.", "Run: qwen auth qwen-oauth", + *([f"Expected credentials file: {status.get('auth_file')}"] if status.get("auth_file") else []), + *([f"Error: {status.get('error')}"] if status.get("error") else [])) return # Try live model discovery, fall back to curated list. @@ -541,12 +536,9 @@ def _model_flow_copilot(config, current_model=""): else: if source in {"GITHUB_TOKEN", "GH_TOKEN"}: from hermes_cli.env_loader import format_secret_source_suffix - print(f" GitHub token: {api_key[:8]}... ✓ ({source}{format_secret_source_suffix(source)})") - elif source == "gh auth token": - print(" GitHub token: ✓ (from `gh auth token`)") + _say(f" GitHub token: {api_key[:8]}... ✓ ({source}{format_secret_source_suffix(source)})", "") else: - print(" GitHub token: ✓") - print() + _say(" GitHub token: ✓ (from `gh auth token`)" if source == "gh auth token" else " GitHub token: ✓", "") effective_base = pconfig.inference_base_url catalog, live_models, _normalize = _copilot_catalog(api_key) @@ -674,14 +666,11 @@ def _model_flow_stepfun(config, current_model=""): current_base = str(model_cfg.get("base_url") or "").strip() current_region = _infer_stepfun_region(current_base or pconfig.inference_base_url) - ordered_regions = [] - for region_key, region_name in (("international", "International"), ("china", "China")): - label = f"{region_name} ({_stepfun_base_url_for_region(region_key)})" - if region_key == current_region: - ordered_regions.insert(0, (region_key, f"{label} ← currently active")) - else: - ordered_regions.append((region_key, label)) - ordered_regions.append(("cancel", "Cancel")) + regions = [(key, f"{name} ({_stepfun_base_url_for_region(key)})") for key, name in + (("international", "International"), ("china", "China"))] + # Active region first, marked; then the other; then Cancel. + ordered_regions = ([(k, f"{label} ← currently active") for k, label in regions if k == current_region] + + [(k, label) for k, label in regions if k != current_region] + [("cancel", "Cancel")]) region_idx = _prompt_provider_choice([label for _, label in ordered_regions]) if region_idx is None or ordered_regions[region_idx][0] == "cancel":