From 3b67606c42462def32fcc5e74513ee939a5880f6 Mon Sep 17 00:00:00 2001 From: teknium1 Date: Mon, 9 Mar 2026 02:38:34 -0700 Subject: [PATCH] fix: custom endpoint provider shows as openrouter in gateway MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three issues caused the gateway to display 'openrouter' instead of 'Custom endpoint' when users configured a custom OAI-compatible endpoint: 1. hermes setup: custom endpoint path saved OPENAI_BASE_URL and OPENAI_API_KEY to .env but never wrote model.provider to config.yaml. All other providers (Codex, z.ai, Kimi, etc.) call _update_config_for_provider() which sets this — custom was the only path that skipped it. Now writes model.provider='custom' and model.base_url to config.yaml. 2. hermes model: custom endpoint set model.provider='auto' in config.yaml. The CLI display had a hack to detect OPENAI_BASE_URL and override to 'custom', but the gateway didn't. Now sets model.provider='custom' directly. 3. gateway /model and /provider commands: defaulted to 'openrouter' and read config.yaml — which had no provider set. Added OPENAI_BASE_URL detection fallback (same pattern the CLI uses) as a defensive catch for existing users who set up before this fix. --- gateway/run.py | 9 +++++++++ hermes_cli/main.py | 2 +- hermes_cli/models.py | 2 +- hermes_cli/setup.py | 22 ++++++++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index 7873cf14..2584521d 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -1449,6 +1449,11 @@ class GatewayRunner: except Exception: current_provider = "openrouter" + # Detect custom endpoint: provider resolved to openrouter but a custom + # base URL is configured — the user set up a custom endpoint. + if current_provider == "openrouter" and os.getenv("OPENAI_BASE_URL", "").strip(): + current_provider = "custom" + if not args: provider_label = _PROVIDER_LABELS.get(current_provider, current_provider) lines = [ @@ -1575,6 +1580,10 @@ class GatewayRunner: except Exception: current_provider = "openrouter" + # Detect custom endpoint + if current_provider == "openrouter" and os.getenv("OPENAI_BASE_URL", "").strip(): + current_provider = "custom" + current_label = _PROVIDER_LABELS.get(current_provider, current_provider) lines = [ diff --git a/hermes_cli/main.py b/hermes_cli/main.py index d10915c8..c2e8bed4 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -1050,7 +1050,7 @@ def _model_flow_custom(config): cfg = load_config() model = cfg.get("model") if isinstance(model, dict): - model["provider"] = "auto" + model["provider"] = "custom" model["base_url"] = effective_url save_config(cfg) deactivate_provider() diff --git a/hermes_cli/models.py b/hermes_cli/models.py index 723f226e..1fdde090 100644 --- a/hermes_cli/models.py +++ b/hermes_cli/models.py @@ -63,7 +63,7 @@ _PROVIDER_LABELS = { "kimi-coding": "Kimi / Moonshot", "minimax": "MiniMax", "minimax-cn": "MiniMax (China)", - "custom": "custom endpoint", + "custom": "Custom endpoint", } _PROVIDER_ALIASES = { diff --git a/hermes_cli/setup.py b/hermes_cli/setup.py index df7a2876..ffb10c14 100644 --- a/hermes_cli/setup.py +++ b/hermes_cli/setup.py @@ -659,6 +659,28 @@ def setup_model_provider(config: dict): if model_name: config['model'] = model_name save_env_value("LLM_MODEL", model_name) + + # Save provider and base_url to config.yaml so the gateway and CLI + # both resolve the correct provider without relying on env-var heuristics. + if base_url: + import yaml + config_path = Path(os.environ.get("HERMES_HOME", Path.home() / ".hermes")) / "config.yaml" + try: + disk_cfg = {} + if config_path.exists(): + disk_cfg = yaml.safe_load(config_path.read_text()) or {} + model_section = disk_cfg.get("model", {}) + if isinstance(model_section, str): + model_section = {"default": model_section} + model_section["provider"] = "custom" + model_section["base_url"] = base_url.rstrip("/") + if model_name: + model_section["default"] = model_name + disk_cfg["model"] = model_section + config_path.write_text(yaml.safe_dump(disk_cfg, sort_keys=False)) + except Exception as e: + logger.debug("Could not save provider to config.yaml: %s", e) + print_success("Custom endpoint configured") elif provider_idx == 4: # Z.AI / GLM