diff --git a/hermes_cli/setup.py b/hermes_cli/setup.py index 1690e48c9..c471b1b9d 100644 --- a/hermes_cli/setup.py +++ b/hermes_cli/setup.py @@ -292,41 +292,12 @@ def _print_setup_summary(config: dict, hermes_home): tool_status = [] - # Vision — works with OpenRouter, Nous OAuth, Codex OAuth, or OpenAI endpoint - _has_vision = False - _vision_via = None + # OpenRouter (required for vision, moa) if get_env_value('OPENROUTER_API_KEY'): - _has_vision, _vision_via = True, "OpenRouter/Gemini" - else: - try: - _vauth_path = Path(os.path.expanduser("~/.hermes/auth.json")) - if _vauth_path.is_file(): - import json as _vjson - _vauth = _vjson.loads(_vauth_path.read_text()) - if _vauth.get("active_provider") == "nous": - _np = _vauth.get("providers", {}).get("nous", {}) - if _np.get("agent_key") or _np.get("access_token"): - _has_vision, _vision_via = True, "Nous Portal/Gemini" - elif _vauth.get("active_provider") == "openai-codex": - _cp = _vauth.get("providers", {}).get("openai-codex", {}) - if _cp.get("tokens", {}).get("access_token"): - _has_vision, _vision_via = True, "OpenAI Codex" - except Exception: - pass - if not _has_vision: - _oai_base = get_env_value('OPENAI_BASE_URL') or "" - if get_env_value('OPENAI_API_KEY') and "api.openai.com" in _oai_base.lower(): - _has_vision, _vision_via = True, "OpenAI" - - if _has_vision: tool_status.append(("Vision (image analysis)", True, None)) - else: - tool_status.append(("Vision (image analysis)", False, "run 'hermes setup' to configure")) - - # Mixture of Agents — requires OpenRouter specifically (calls multiple models) - if get_env_value('OPENROUTER_API_KEY'): tool_status.append(("Mixture of Agents", True, None)) else: + tool_status.append(("Vision (image analysis)", False, "OPENROUTER_API_KEY")) tool_status.append(("Mixture of Agents", False, "OPENROUTER_API_KEY")) # Firecrawl (web tools) @@ -918,104 +889,22 @@ def setup_model_provider(config: dict): # else: provider_idx == 9 (Keep current) — only shown when a provider already exists - # ── Vision & Image Analysis Setup ── - # Vision requires a multimodal-capable provider. Check whether the user's - # chosen provider already covers it — if so, skip the prompt entirely. - _vision_needs_setup = True - - if selected_provider == "openrouter": - # OpenRouter → Gemini for vision, already configured - _vision_needs_setup = False - elif selected_provider == "nous": - # Nous Portal OAuth → Gemini via Nous, already configured - _vision_needs_setup = False - elif selected_provider == "openai-codex": - # Codex OAuth → gpt-5.3-codex supports vision - _vision_needs_setup = False - elif selected_provider == "custom": - _custom_base = (get_env_value("OPENAI_BASE_URL") or "").lower() - if "api.openai.com" in _custom_base: - # Direct OpenAI endpoint — show vision model picker - print() - print_header("Vision Model") - print_info("Your OpenAI endpoint supports vision. Pick a model for image analysis:") - _oai_vision_models = ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini", "gpt-4.1-nano"] - _vm_choices = _oai_vision_models + [f"Keep default (gpt-4o-mini)"] - _vm_idx = prompt_choice("Select vision model:", _vm_choices, len(_vm_choices) - 1) - if _vm_idx < len(_oai_vision_models): - save_env_value("AUXILIARY_VISION_MODEL", _oai_vision_models[_vm_idx]) - print_success(f"Vision model set to {_oai_vision_models[_vm_idx]}") - _vision_needs_setup = False - - # Even for providers without native vision, check if existing credentials - # from a previous setup already cover it (e.g. user had OpenRouter before - # switching to z.ai) - if _vision_needs_setup: - if get_env_value("OPENROUTER_API_KEY"): - _vision_needs_setup = False - else: - # Check for Nous Portal OAuth in auth.json - try: - _auth_path = Path.home() / ".hermes" / "auth.json" - if _auth_path.is_file(): - import json as _json - _auth_data = _json.loads(_auth_path.read_text()) - if _auth_data.get("active_provider") == "nous": - _nous_p = _auth_data.get("providers", {}).get("nous", {}) - if _nous_p.get("agent_key") or _nous_p.get("access_token"): - _vision_needs_setup = False - except Exception: - pass - - if _vision_needs_setup: - _prov_names = { - "nous-api": "Nous Portal API key", - "zai": "Z.AI / GLM", - "kimi-coding": "Kimi / Moonshot", - "minimax": "MiniMax", - "minimax-cn": "MiniMax CN", - "custom": "your custom endpoint", - } - _prov_display = _prov_names.get(selected_provider, selected_provider or "your provider") - - print() - print_header("Vision & Image Analysis (optional)") - print_info(f"Vision requires a multimodal-capable provider. {_prov_display}") - print_info("doesn't natively support it. Choose how to enable vision,") - print_info("or skip to configure later.") + # ── OpenRouter API Key for tools (if not already set) ── + # Tools (vision, web, MoA) use OpenRouter independently of the main provider. + # Prompt for OpenRouter key if not set and a non-OpenRouter provider was chosen. + if selected_provider in ("nous", "nous-api", "openai-codex", "custom", "zai", "kimi-coding", "minimax", "minimax-cn") and not get_env_value("OPENROUTER_API_KEY"): print() + print_header("OpenRouter API Key (for tools)") + print_info("Tools like vision analysis, web search, and MoA use OpenRouter") + print_info("independently of your main inference provider.") + print_info("Get your API key at: https://openrouter.ai/keys") - _vision_choices = [ - "OpenRouter — uses Gemini (free tier at openrouter.ai/keys)", - "OpenAI — enter API key & choose a vision model", - "Skip for now", - ] - _vision_idx = prompt_choice("Configure vision:", _vision_choices, 2) - - if _vision_idx == 0: # OpenRouter - _or_key = prompt(" OpenRouter API key", password=True) - if _or_key: - save_env_value("OPENROUTER_API_KEY", _or_key) - print_success("OpenRouter key saved — vision will use Gemini") - else: - print_info("Skipped — vision won't be available") - elif _vision_idx == 1: # OpenAI - _oai_key = prompt(" OpenAI API key", password=True) - if _oai_key: - save_env_value("OPENAI_API_KEY", _oai_key) - save_env_value("OPENAI_BASE_URL", "https://api.openai.com/v1") - _oai_vision_models = ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini", "gpt-4.1-nano"] - _vm_choices = _oai_vision_models + ["Use default (gpt-4o-mini)"] - _vm_idx = prompt_choice("Select vision model:", _vm_choices, 0) - if _vm_idx < len(_oai_vision_models): - save_env_value("AUXILIARY_VISION_MODEL", _oai_vision_models[_vm_idx]) - print_success(f"Vision configured with OpenAI ({_oai_vision_models[_vm_idx]})") - else: - print_success("Vision configured with OpenAI (gpt-4o-mini)") - else: - print_info("Skipped — vision won't be available") + api_key = prompt(" OpenRouter API key (optional, press Enter to skip)", password=True) + if api_key: + save_env_value("OPENROUTER_API_KEY", api_key) + print_success("OpenRouter API key saved (for tools)") else: - print_info("Skipped — add later with 'hermes config set OPENROUTER_API_KEY ...'") + print_info("Skipped - some tools (vision, web scraping) won't work without this") # ── Model Selection (adapts based on provider) ── if selected_provider != "custom": # Custom already prompted for model name