diff --git a/hermes_cli/model_setup_flows.py b/hermes_cli/model_setup_flows.py index c227aa7c12..90a02016ae 100644 --- a/hermes_cli/model_setup_flows.py +++ b/hermes_cli/model_setup_flows.py @@ -1,9 +1,9 @@ """Per-provider model-selection wizard flows for ``hermes setup`` / ``hermes model``. -main.py re-imports every ``_model_flow_*`` (tests patch ``hermes_cli.main._model_flow_*``). main / -config / auth / models helpers are imported lazily inside bodies: avoids the main.py import cycle -and lets tests patch ``hermes_cli.config.load_config`` etc. at call time. The shared skeleton is -:mod:`hermes_cli.model_setup_flows_common`, re-exported here. +main / config / auth / models helpers are imported lazily inside bodies: avoids the main.py import +cycle and lets tests patch ``hermes_cli.config.load_config`` etc. at call time. The shared skeleton +lives in :mod:`hermes_cli.model_setup_flows_common`; the custom / Azure / Bedrock flows live in their +own ``model_setup_flows_*`` modules. """ from __future__ import annotations @@ -13,17 +13,15 @@ import argparse import os from hermes_cli.config import clear_model_endpoint_credentials -from hermes_cli.model_setup_flows_common import ( # noqa: F401 - _HTTP, _activate_provider_model, _ask, _begin_model_config, _commit_model_config, _curses_choice, - _ensure_dict_section, _ensure_flow_api_key, _existing_api_key_for_model_flow, _finish_model, +from hermes_cli.model_setup_flows_common import ( + _HTTP, _activate_provider_model, _ask, _commit_model_config, _curses_choice, + _ensure_dict_section, _ensure_flow_api_key, _finish_model, _load_config_model_section, _models_dev_merged, _oauth_gate, _persist_model, _pick_model_or_prompt, - _print_numbered, _prompt_auth_credentials_choice, _prune_replaced_custom_model_config_credentials, + _print_numbered, _prompt_auth_credentials_choice, _run_login, _say, _show_curated) -from hermes_cli.model_setup_flows_custom import _model_flow_custom, _model_flow_named_custom # noqa: F401 -from hermes_cli.model_setup_flows_azure import _model_flow_azure_foundry # noqa: F401 -from hermes_cli.model_setup_flows_bedrock import ( # noqa: F401 - BEDROCK_GEO_PREFIXES, bedrock_region_geo_prefix, bedrock_model_routable_from_region, - _model_flow_bedrock_api_key, _model_flow_bedrock) +from hermes_cli.model_setup_flows_custom import _model_flow_custom, _model_flow_named_custom +from hermes_cli.model_setup_flows_azure import _model_flow_azure_foundry +from hermes_cli.model_setup_flows_bedrock import _model_flow_bedrock def _env_base_url(base_url_env: str) -> str: @@ -64,7 +62,8 @@ def _model_flow_openrouter(config, current_model=""): if abort: return - from hermes_cli.models import model_ids, get_pricing_for_provider + from hermes_cli.models import model_ids + from hermes_cli.models_pricing import get_pricing_for_provider openrouter_models = model_ids(force_refresh=True) # Live pricing is non-blocking — empty dict on failure. pricing = get_pricing_for_provider("openrouter", force_refresh=True) @@ -90,7 +89,8 @@ def _model_flow_ai_gateway(config, current_model=""): if abort: return - from hermes_cli.models import ai_gateway_model_ids, get_pricing_for_provider + from hermes_cli.models import ai_gateway_model_ids + from hermes_cli.models_pricing import get_pricing_for_provider models_list = ai_gateway_model_ids(force_refresh=True) pricing = get_pricing_for_provider("ai-gateway", force_refresh=True) selected = _prompt_model_selection(models_list, current_model=current_model, pricing=pricing) @@ -168,9 +168,12 @@ def _nous_login_args(args) -> argparse.Namespace: def _nous_model_catalog(free_tier: bool, portal_url: str, model_ids: list, pricing: dict): """Free/paid-tier catalog for the Nous picker: ``(model_ids, pricing, unavailable_models, unavailable_message, policy_narrowed)`` or None (message already printed) when nothing is selectable.""" + from hermes_cli.models_pricing import nous_policy_allowed_ids, restrict_to_nous_policy from hermes_cli.models import ( - nous_policy_allowed_ids, partition_nous_models_by_tier, restrict_to_nous_policy, - union_with_portal_free_recommendations, union_with_portal_paid_recommendations) + partition_nous_models_by_tier, + union_with_portal_free_recommendations, + union_with_portal_paid_recommendations, + ) # Free users: union with the Portal's freeRecommendedModels (newly launched free models appear # before the curated list catches up), then partition selectable/unavailable by Portal pricing. @@ -283,7 +286,8 @@ def _model_flow_nous(config, current_model="", args=None): # Already logged in — the curated list (agentic models users know from OpenRouter) # instead of the hundreds returned by the live /models endpoint. - from hermes_cli.models import check_nous_free_tier, get_curated_nous_model_ids, get_pricing_for_provider + from hermes_cli.models import check_nous_free_tier, get_curated_nous_model_ids + from hermes_cli.models_pricing import get_pricing_for_provider model_ids = get_curated_nous_model_ids() if not model_ids: print("No curated models available for Nous Portal.") @@ -814,7 +818,7 @@ def _gemini_tier_ok(existing_key: str, pconfig, base_url_env: str) -> bool: def _lmstudio_models(pconfig, curated, api_key, base_url): """LM Studio: live /api/v1/models probe only.""" from hermes_cli.auth import AuthError - from hermes_cli.models import fetch_lmstudio_models + from hermes_cli.models_local import fetch_lmstudio_models try: model_list = fetch_lmstudio_models(api_key=api_key, base_url=base_url) except AuthError as exc: @@ -948,7 +952,7 @@ def _model_flow_api_key_provider(config, provider_id, current_model=""): pricing: dict = {} if model_list: try: - from hermes_cli.models import get_pricing_for_provider + from hermes_cli.models_pricing import get_pricing_for_provider pricing = get_pricing_for_provider(provider_id) or {} except Exception: pricing = {} diff --git a/tests/hermes_cli/test_bedrock_mantle_key_env.py b/tests/hermes_cli/test_bedrock_mantle_key_env.py index 824ca3947b..48f8733320 100644 --- a/tests/hermes_cli/test_bedrock_mantle_key_env.py +++ b/tests/hermes_cli/test_bedrock_mantle_key_env.py @@ -14,7 +14,7 @@ import os import yaml import hermes_cli.runtime_provider as rp -from hermes_cli.model_setup_flows import _model_flow_bedrock_api_key +from hermes_cli.model_setup_flows_bedrock import _model_flow_bedrock_api_key REGION = "us-east-1" diff --git a/tests/hermes_cli/test_bedrock_region_scoped_picker.py b/tests/hermes_cli/test_bedrock_region_scoped_picker.py index 8786a839ee..37a3a32b38 100644 --- a/tests/hermes_cli/test_bedrock_region_scoped_picker.py +++ b/tests/hermes_cli/test_bedrock_region_scoped_picker.py @@ -5,7 +5,7 @@ route from endpoints in their own geography. Offering us.* profiles to an eu-central-2 picker produces configs AWS rejects regardless of credentials. """ -from hermes_cli.model_setup_flows import ( +from hermes_cli.model_setup_flows_bedrock import ( BEDROCK_GEO_PREFIXES, bedrock_model_routable_from_region, bedrock_region_geo_prefix, diff --git a/tests/hermes_cli/test_keyed_provider_credential_pool.py b/tests/hermes_cli/test_keyed_provider_credential_pool.py index 45308e4165..e059ed7542 100644 --- a/tests/hermes_cli/test_keyed_provider_credential_pool.py +++ b/tests/hermes_cli/test_keyed_provider_credential_pool.py @@ -152,7 +152,7 @@ def test_prune_keeps_active_legacy_pool_for_keyed_provider(tmp_path, monkeypatch encoding="utf-8", ) - from hermes_cli.model_setup_flows import ( + from hermes_cli.model_setup_flows_common import ( _prune_replaced_custom_model_config_credentials, ) diff --git a/tests/hermes_cli/test_model_flow_pooled_credentials.py b/tests/hermes_cli/test_model_flow_pooled_credentials.py index a6a2542c62..000a5a71fa 100644 --- a/tests/hermes_cli/test_model_flow_pooled_credentials.py +++ b/tests/hermes_cli/test_model_flow_pooled_credentials.py @@ -5,7 +5,7 @@ from __future__ import annotations from unittest.mock import patch from hermes_cli.auth import PROVIDER_REGISTRY -from hermes_cli.model_setup_flows import _existing_api_key_for_model_flow +from hermes_cli.model_setup_flows_common import _existing_api_key_for_model_flow class _PoolEntry: @@ -57,7 +57,7 @@ def test_generic_api_key_flow_passes_pool_key_to_existing_key_prompt(monkeypatch def test_bedrock_flow_sees_pool_key_when_no_env(monkeypatch, capsys): """Bedrock API-key mode must also see pool-backed credentials.""" - from hermes_cli.model_setup_flows import _model_flow_bedrock_api_key + from hermes_cli.model_setup_flows_bedrock import _model_flow_bedrock_api_key monkeypatch.delenv("AWS_BEARER_TOKEN_BEDROCK", raising=False) diff --git a/tests/hermes_cli/test_model_switch_custom_providers.py b/tests/hermes_cli/test_model_switch_custom_providers.py index 7073ad4262..259302d211 100644 --- a/tests/hermes_cli/test_model_switch_custom_providers.py +++ b/tests/hermes_cli/test_model_switch_custom_providers.py @@ -1577,7 +1577,7 @@ def test_model_flow_named_custom_persists_discovered_models(monkeypatch): ), ) - from hermes_cli.model_setup_flows import _model_flow_named_custom + from hermes_cli.model_setup_flows_custom import _model_flow_named_custom _model_flow_named_custom( {},