refactor(hermes_cli): pack re-export imports and closers in setup flows
This commit is contained in:
@@ -233,8 +233,7 @@ _SYNC_USAGE = (
|
||||
" device [--name N] Show or set this device's label\n"
|
||||
"\n"
|
||||
"Shared with your team:\n"
|
||||
" propose <skill> Share a skill with your organisation"
|
||||
)
|
||||
" propose <skill> Share a skill with your organisation")
|
||||
|
||||
|
||||
def _sync_device(args, ssc) -> int:
|
||||
|
||||
@@ -28,8 +28,7 @@ _GENERIC_API_KEY_PROVIDERS = frozenset({
|
||||
"openai-api", "gemini", "deepseek", "xai", "zai", "kimi-coding-cn",
|
||||
"minimax", "minimax-cn", "kilocode", "opencode-zen", "opencode-go",
|
||||
"opencode-free", "alibaba", "huggingface", "xiaomi", "arcee", "gmi",
|
||||
"nvidia", "ollama-cloud", "tencent-tokenhub", "tencent-tokenplan", "lmstudio",
|
||||
})
|
||||
"nvidia", "ollama-cloud", "tencent-tokenhub", "tencent-tokenplan", "lmstudio"})
|
||||
|
||||
|
||||
def _short_url(url: str) -> str:
|
||||
@@ -70,8 +69,7 @@ _AUX_TASKS: list[tuple[str, str, str]] = [
|
||||
("triage_specifier", "Triage specifier", "kanban spec fleshing"),
|
||||
("kanban_decomposer", "Kanban decomposer", "task decomposition"),
|
||||
("profile_describer", "Profile describer", "auto profile descriptions"),
|
||||
("curator", "Curator", "skill-usage review pass"),
|
||||
]
|
||||
("curator", "Curator", "skill-usage review pass")]
|
||||
|
||||
# Special non-auxiliary task surfaced in the same picker: subagent delegation. Routing lives
|
||||
# under top-level `delegation.*` (NOT `auxiliary.delegation`) because delegate_task spawns full
|
||||
@@ -208,8 +206,7 @@ def _aux_config_menu() -> None:
|
||||
entries = [
|
||||
(task_key, f"{name.ljust(name_col)}{('(' + desc + ')').ljust(desc_col)}"
|
||||
f"{_format_aux_current(_aux_task_cfg(cfg, task_key))}")
|
||||
for task_key, name, desc in menu_tasks
|
||||
]
|
||||
for task_key, name, desc in menu_tasks]
|
||||
entries.append(("__reset__", "Reset all to auto"))
|
||||
entries.append(("__back__", "Back"))
|
||||
|
||||
@@ -380,9 +377,7 @@ def _prompt_provider_choice(choices, *, default=0, title="Select provider:"):
|
||||
|
||||
|
||||
_DEFAULT_QWEN_PORTAL_MODELS = [
|
||||
"qwen3-coder-plus",
|
||||
"qwen3-coder",
|
||||
]
|
||||
"qwen3-coder-plus", "qwen3-coder"]
|
||||
|
||||
|
||||
# (mode value, label, description, accepted answers); "" = auto-detect
|
||||
@@ -394,8 +389,7 @@ _CUSTOM_API_MODES = (
|
||||
("codex_responses", "Responses / Codex", "Use /responses for Codex-compatible tool-calling backends.",
|
||||
("3", "responses", "codex", "codex_responses")),
|
||||
("anthropic_messages", "Anthropic Messages", "Use /v1/messages for Anthropic-compatible endpoints.",
|
||||
("4", "anthropic", "anthropic_messages", "messages")),
|
||||
)
|
||||
("4", "anthropic", "anthropic_messages", "messages")))
|
||||
_CUSTOM_API_MODE_ANSWERS = {answer: value for value, _, _, answers in _CUSTOM_API_MODES for answer in answers}
|
||||
|
||||
|
||||
@@ -529,8 +523,7 @@ def _remove_custom_provider(config):
|
||||
print("Remove a custom provider:\n")
|
||||
choices = [
|
||||
f"{entry.get('name', 'unnamed')} ({_short_url(entry.get('base_url', ''))})" if isinstance(entry, dict) else str(entry)
|
||||
for entry in providers
|
||||
]
|
||||
for entry in providers]
|
||||
choices.append("Cancel")
|
||||
|
||||
try:
|
||||
@@ -815,8 +808,7 @@ def _named_custom_provider_map(cfg) -> dict[str, dict[str, str]]:
|
||||
"api_mode": entry.get("api_mode", ""),
|
||||
"provider_key": provider_key,
|
||||
"api_key_ref": _lookup_ref(raw_api_key_refs, name, provider_key, model),
|
||||
"base_url_ref": _lookup_ref(raw_base_url_refs, name, provider_key, model),
|
||||
}
|
||||
"base_url_ref": _lookup_ref(raw_base_url_refs, name, provider_key, model)}
|
||||
return custom_provider_map
|
||||
|
||||
|
||||
@@ -835,8 +827,7 @@ def _build_provider_picker_rows(config: dict, active: str, provider_labels: dict
|
||||
_cli_excluded = {
|
||||
str(p).strip().lower()
|
||||
for p in (config.get("model_catalog", {}) or {}).get("excluded_providers") or []
|
||||
if p
|
||||
}
|
||||
if p}
|
||||
if _cli_excluded:
|
||||
# A canonical provider is hidden if its slug OR any alias is excluded.
|
||||
_names_for: dict[str, set[str]] = {_p.slug: {_p.slug.lower()} for _p in CANONICAL_PROVIDERS}
|
||||
|
||||
@@ -15,38 +15,18 @@ 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,
|
||||
_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,
|
||||
_run_login,
|
||||
_say,
|
||||
_show_curated)
|
||||
from hermes_cli.model_setup_flows_custom import ( # noqa: F401
|
||||
_model_flow_custom,
|
||||
_model_flow_named_custom)
|
||||
from hermes_cli.model_setup_flows_azure import ( # noqa: F401
|
||||
_model_flow_azure_foundry)
|
||||
_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,
|
||||
_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,
|
||||
_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)
|
||||
BEDROCK_GEO_PREFIXES, bedrock_region_geo_prefix, bedrock_model_routable_from_region,
|
||||
_model_flow_bedrock_api_key, _model_flow_bedrock,
|
||||
)
|
||||
|
||||
|
||||
def _env_base_url(base_url_env: str) -> str:
|
||||
@@ -75,6 +55,20 @@ def _report_live_models(model_list, source: str) -> None:
|
||||
print(f" Found {len(model_list)} model(s) from {source}")
|
||||
|
||||
|
||||
def _aggregator_flow(provider_id: str, label: str, base_url: str, current_model: str, existing_key: str,
|
||||
resolved_key: str, fetch_ids, *, clear_creds: bool = True, **pick_kw) -> None:
|
||||
"""Shared tail of the OpenRouter / AI Gateway flows: live catalog + pricing, picker, persist."""
|
||||
from hermes_cli.auth import _prompt_model_selection
|
||||
from hermes_cli.models import get_pricing_for_provider
|
||||
|
||||
models_list = fetch_ids(force_refresh=True)
|
||||
# Live pricing is non-blocking — empty dict on failure.
|
||||
pricing = get_pricing_for_provider(provider_id, force_refresh=True)
|
||||
selected = _prompt_model_selection(models_list, current_model=current_model, pricing=pricing, **pick_kw)
|
||||
_finish_model(selected, provider_id, f"Default model set to: {selected} (via {label})",
|
||||
base_url=base_url, api_mode="chat_completions", clear_creds=clear_creds)
|
||||
|
||||
|
||||
def _model_flow_openrouter(config, current_model=""):
|
||||
"""OpenRouter provider: ensure API key, then pick model."""
|
||||
from hermes_constants import OPENROUTER_BASE_URL
|
||||
|
||||
@@ -46,8 +46,7 @@ def _azure_entra_preflight(current_entra: dict):
|
||||
try:
|
||||
from agent.azure_identity_adapter import (
|
||||
EntraIdentityConfig, SCOPE_AI_AZURE_DEFAULT, build_token_provider, describe_active_credential,
|
||||
has_azure_identity_installed,
|
||||
)
|
||||
has_azure_identity_installed)
|
||||
except ImportError as exc:
|
||||
_say("", f"⚠ Could not import azure-identity adapter: {exc}", " Falling back to API key auth.")
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user