Repository navigation
Description
Upstream issue draft — hermes-muse-code v0.6.0
Title: v0.6.0 loopback wire adapter never receives traffic: profile.base_url mutation is not read by runtime credential resolution (runtime_base_url not overridden)
Component: plugin __init__.py (MuseCodeSubscriptionProfile) vs Hermes hermes_cli/auth.py / providers/base.py
Summary
On Hermes ≥ 0.22.0, resolve_api_key_provider_credentials() (hermes_cli/auth.py:2236) derives the runtime base URL via ProviderProfile.runtime_base_url(...). The base-class implementation returns None (providers/base.py:630), and MuseCodeSubscriptionProfile does not override it. As a result, resolution falls through to _default_api_key_base_url() → pconfig.inference_base_url (https://api.meta.ai/v1), so every inference request goes directly to Meta even though the loopback adapter is running and bound.
Observed (all verified on-disk)
register()runs; the adapter starts and listens on127.0.0.1:43219(DEFAULT_PORTS43219-43222) in the gateway process (confirmed vialsof).- The provider profile is constructed with
base_url=_adapter_base_url()and_refresh_base_url()keeps it pointed at the loopback URL — but nothing in the runtime resolution path readsprofile.base_url. It is a dead write. - Request dumps show
url = https://api.meta.ai/v1/responses(direct, not loopback), with raw (un-aliased) tool names in the payload. - Meta answers
403 client_attestation_denied("This API key is billed to a Muse Code subscription... use it in Muse Code") — exactly what the wire adapter exists to prevent.
Note for maintainers
Because base_url_env_var is left empty in the profile constructor, there is also no <PROVIDER>_BASE_URL-style env override users could set as a workaround; the only escape hatches are the code path above or a registry resolver entry.
Suggested minimal fix (inside MuseCodeSubscriptionProfile)
def runtime_base_url(self, *, api_key, default, env_url):
return self.base_url or Noneself.base_url is already maintained at construction and by register() → _refresh_base_url(), so it tracks the adapter (loopback when bound, DEFAULT_BASE_URL fallback otherwise).
Verified live (post-fix)
With the override added (and the plugin correctly registered), the loopback adapter receives traffic and a live subscription request succeeds end-to-end: request goes to http://127.0.0.1:<port>/v1/responses, tool names are aliased on the wire, and Meta answers 200. The override is confirmed necessary and sufficient for routing.
Environment
- Hermes 0.22.x (macOS, arm64), plugin v0.6.0 (commit b419754), subscription credential via device login,
MUSE_CODE_SUB_TOKENset in the profile .env.
Activity
TheStreamCode commentedon Nov 8, 2026
Thanks for the detailed report, and for verifying the live behavior after the override. The diagnosis is correct:
runtime_base_url()is the only hookresolve_api_key_provider_credentials()reads, the base implementation returnsNone, and this profile never overrode it, sobase_urlwas never consulted at runtime.Fix is in #13: the profile now returns the adapter URL (or the direct endpoint when the adapter could not bind), with a regression test and a before/after check against the upstream resolution path. It will land in the next release.
fix(provider): route runtime inference through the wire adapter (#13)
TheStreamCode commentedon Nov 8, 2026
Fixed in v0.6.1:
runtime_base_url()now returns the adapter URL, with regression tests for the routed path and the fallback to the direct endpoint when the adapter cannot bind.https://github.com/TheStreamCode/hermes-muse-code/releases/tag/v0.6.1
Closing as fixed. Please reopen if anything still misbehaves on 0.6.1.