diff --git a/hermes_cli/runtime_provider.py b/hermes_cli/runtime_provider.py index c77545b983088..bc8b25924b7ca 100644 --- a/hermes_cli/runtime_provider.py +++ b/hermes_cli/runtime_provider.py @@ -2188,6 +2188,22 @@ def resolve_runtime_provider( pconfig = PROVIDER_REGISTRY.get(provider) if pconfig and pconfig.auth_type == "api_key": creds = resolve_api_key_provider_credentials(provider) + # Actual Computer: a loopback base_url configured in model_cfg (not + # just env) selects the daemon's local offline API, which requires no + # auth. Inject the placeholder BEFORE the usable-secret gate below, + # mirroring the env-driven path inside the credential resolver. + if provider == "actual" and not has_usable_secret(creds.get("api_key")): + _cfg_provider = str(model_cfg.get("provider") or "").strip().lower() + _cfg_url = "" + if _cfg_provider == provider: + _cfg_url = (model_cfg.get("base_url") or "").strip().rstrip("/") + _effective_url = normalize_actual_base_url( + _cfg_url or creds.get("base_url", "").rstrip("/") + ) + if is_actual_local_base_url(_effective_url): + creds = dict(creds) + creds["api_key"] = ACTUAL_LOCAL_NOAUTH_PLACEHOLDER + creds["source"] = creds.get("source") or "local-offline" # An explicitly selected API-key provider is authoritative. Returning # a runtime with an empty key defers failure until the first request and # can make a later fallback look like a silent provider switch. Fail at diff --git a/plugins/model-providers/actual/__init__.py b/plugins/model-providers/actual/__init__.py index b2102f562572a..123892d4a6862 100644 --- a/plugins/model-providers/actual/__init__.py +++ b/plugins/model-providers/actual/__init__.py @@ -46,10 +46,11 @@ class ActualProfile(ProviderProfile): self, *, api_key: str | None = None, + base_url: str | None = None, timeout: float = 8.0, ) -> list[str] | None: base_url = _normalize_actual_base_url( - os.getenv("ACTUAL_BASE_URL", "").strip() or self.base_url + os.getenv("ACTUAL_BASE_URL", "").strip() or base_url or self.base_url ) if not base_url: return None diff --git a/tests/hermes_cli/test_actual_provider.py b/tests/hermes_cli/test_actual_provider.py index aac61d6ecbf1e..37d50ad8ac6a8 100644 --- a/tests/hermes_cli/test_actual_provider.py +++ b/tests/hermes_cli/test_actual_provider.py @@ -195,4 +195,7 @@ def test_actual_provider_model_ids_use_local_profile_catalog(monkeypatch): with patch.object(profile, "fetch_models", return_value=["actual/local-model"]) as fetch: assert provider_model_ids("actual") == ["actual/local-model"] - fetch.assert_called_once_with(api_key=ACTUAL_LOCAL_NOAUTH_PLACEHOLDER) + fetch.assert_called_once_with( + api_key=ACTUAL_LOCAL_NOAUTH_PLACEHOLDER, + base_url=DEFAULT_ACTUAL_LOCAL_BASE_URL, + )