From 87e6acbea989b1cec8497fca24ec4b7960e73d77 Mon Sep 17 00:00:00 2001 From: Omar Baradei Date: Thu, 28 May 2026 10:58:40 -0700 Subject: [PATCH 1/2] fix: honour HERMES_LLM_BASE_URL in runtime_provider.py api_key path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kimi worker added the fallback to hermes_cli/auth.py:resolve_api_key_provider_credentials() but the caller at runtime_provider.py:1163 already set base_url = pconfig.inference_base_url before creds were consulted — so the creds base_url was never used for non-kimi providers. Add the same HERMES_LLM_BASE_URL fallback at runtime_provider.py:1154 so env_url carries the proxy URL through to line 1163's base_url resolution. Refs meshboard task: stream-tap-runtime-provider-env-override --- hermes_cli/runtime_provider.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hermes_cli/runtime_provider.py b/hermes_cli/runtime_provider.py index c40316e02ccf..a3e4643e77d8 100644 --- a/hermes_cli/runtime_provider.py +++ b/hermes_cli/runtime_provider.py @@ -1153,6 +1153,12 @@ def _resolve_explicit_runtime( env_url = "" if pconfig.base_url_env_var: env_url = os.getenv(pconfig.base_url_env_var, "").strip().rstrip("/") + # MeshBoard stream-tap launcher sets HERMES_LLM_BASE_URL to a local + # proxy URL. Honour it when the provider-specific env var is absent + # so the tap proxy actually receives inference traffic instead of + # being silently bypassed in favour of the default upstream URL. + if not env_url: + env_url = os.getenv("HERMES_LLM_BASE_URL", "").strip().rstrip("/") base_url = explicit_base_url if not base_url: From 265424529ac909d86846e25fceff3fb5059a158b Mon Sep 17 00:00:00 2001 From: Omar Baradei Date: Thu, 28 May 2026 11:01:33 -0700 Subject: [PATCH 2/2] fix: honour HERMES_LLM_BASE_URL in pool-based runtime provider resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix (auth.py + runtime_provider.py _resolve_explicit_runtime path) missed the pool-based code path in _resolve_runtime_from_pool_entry(). For providers like opencode-zen that resolve via the credential pool, the base_url was set from the pool entry's default without checking HERMES_LLM_BASE_URL. Add the override at line 306 (right after base_url is read from the pool entry) so the MeshBoard stream-tap proxy URL is honoured regardless of which resolution path is taken: explicit, named-custom, or pool. This is the actual code path exercised by MeshBoard dispatches, which use resolve_runtime_provider(requested='opencode-zen') → pool → _resolve_runtime_from_pool_entry. Refs meshboard task: stream-tap-runtime-provider-env-override --- hermes_cli/runtime_provider.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hermes_cli/runtime_provider.py b/hermes_cli/runtime_provider.py index a3e4643e77d8..0b4a6f1151d2 100644 --- a/hermes_cli/runtime_provider.py +++ b/hermes_cli/runtime_provider.py @@ -304,6 +304,15 @@ def _resolve_runtime_from_pool_entry( # config.default was still a Claude model. effective_model = (target_model or model_cfg.get("default") or "") base_url = (getattr(entry, "runtime_base_url", None) or getattr(entry, "base_url", None) or "").rstrip("/") + # MeshBoard stream-tap launcher sets HERMES_LLM_BASE_URL to a local + # loopback proxy URL when the stream-tap is active. This env var + # must override the pool's default base_url so inference traffic + # is routed through the proxy and captured as JSONL for the + # dashboard. Without this, Hermes bypasses the tap entirely and + # the dashboard shows "model silent" during active dispatches. + _tap_url = os.getenv("HERMES_LLM_BASE_URL", "").strip().rstrip("/") + if _tap_url: + base_url = _tap_url api_key = getattr(entry, "runtime_api_key", None) or getattr(entry, "access_token", "") api_mode = "chat_completions" if provider == "openai-codex":