fix: honour HERMES_LLM_BASE_URL in runtime_provider.py api_key resolution path - #20
Merged
Merged
Conversation
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
🔎 Lint report:
|
…tion 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
OmarB97
added a commit
that referenced
this pull request
Jun 10, 2026
…lice 4.0, hermes side) (#162) The hermes half of cloud channels slice 4.0 (cloud half = meshboard-cloud #20, deployed + live-verified today): promote a session to a cloud channel and tail its local message log into it, so the owner's other devices can read the conversation even when this gateway is offline. - tui_gateway/cloud_channels.py: stdlib-only client (urllib) + one daemon pusher thread per shared session. Reads rows past an id watermark via its own read-only sqlite connection (no SessionDB coupling), maps them with the pure rows_to_batch (sender_device attribution preserved; user rows fall back to this device's name), pushes batches; cloud-side dedupe makes the watermark purely an optimisation, so crash/replay is safe. Cloud being down never affects the local session (errors log once per change and back off). - server.py: session.cloud_share / cloud_status / cloud_unshare RPCs. Resolve stored-or-runtime ids and do NOT require a live session (the pusher reads sqlite). Hard zero-dep gate: refused with a clear message unless the operator set HERMES_CLOUD_TOKEN — the core never dials the cloud on its own. - Desktop: "Share to cloud" in the session actions menu (en/zh/ja/zh-hant), self-contained like Export; all outcomes are plain-English toasts, including the not-configured case. Tests: 6 (row→batch mapping incl. attribution fallback + role filtering; pusher watermark/tail/no-op/error semantics against a real sqlite file with the network monkeypatched; the opt-in gate). tui_gateway suite 125 passed; tsc/eslint/ruff clean. Co-authored-by: Omar Baradei <omar@kostudios.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Adds a
HERMES_LLM_BASE_URLenv var fallback inhermes_cli/runtime_provider.pyat theenv_urlresolution step (line 1155). When the provider-specific env var (e.g.OPENCODE_ZEN_BASE_URL) is unset, the code now reads the genericHERMES_LLM_BASE_URLbefore falling back to the hardcodedpconfig.inference_base_url.Why
MeshBoard's stream-tap launcher creates a per-dispatch sandbox whose
.envsetsHERMES_LLM_BASE_URLto a local loopback proxy URL (e.g.http://127.0.0.1:55176). Hermes was ignoring it because:HERMES_LLM_BASE_URLin the subprocess env.envalso sets it (dotenv loads withoverride=True)resolve_runtime_provider()never readsHERMES_LLM_BASE_URL— it only checkspconfig.base_url_env_var(provider-specific) and then falls back to the hardcoded default URLThis caused the stream-tap proxy to receive zero traffic, leaving the dashboard stream rows completely silent during active dispatches.
The earlier fix (commit
a73ee55c2) added the fallback tohermes_cli/auth.py:resolve_api_key_provider_credentials()— but the caller at line 1163 already setbase_url = env_url or pconfig.inference_base_urlBEFORE creds were consulted. The credsbase_urlwas never used for non-kimi providers because line 1169's guardif not base_url:was already False.How to Review
cd tests && python3 -m pytest hermes_cli/test_runtime_provider*.py -x --tb=shortEvidence
HERMES_LLM_BASE_URL=http://127.0.0.1:9999 python3 -c "from hermes_cli.runtime_provider import resolve_runtime_provider; r = resolve_runtime_provider(requested='opencode-zen'); print(r['base_url'])"should printhttp://127.0.0.1:9999instead of the default opencode-zen URL.Verification
Pass expected: existing resolve-runtime tests unaffected (env var only activates when provider-specific var is absent).
Risks / Gaps
HERMES_SKIP_PROFILE_OVERRIDE=1so the sandbox HERMES_HOME is not clobbered by_apply_profile_override()Collaborators
Participants: ko-mac.hermes (launcher), MeshBoard stream-tap worker
Process: MeshBoard autopilot dispatch → stream-tap proxy → Hermes subprocess
Task context: stream-tap-empty-jsonl-diagnostic (resolved root cause: Hermes bypassed tap due to missing env var consumption)
Related work: hermes-agent PR #33986 (HERMES_SKIP_PROFILE_OVERRIDE), fork main commit a73ee55 (auth.py fallback)