fix(doctor): flag missing credentials for active openrouter provider
This commit is contained in:
@@ -651,31 +651,41 @@ def run_doctor(args):
|
|||||||
|
|
||||||
# Check credentials for the configured provider.
|
# Check credentials for the configured provider.
|
||||||
# Limit to API-key providers in PROVIDER_REGISTRY — other provider
|
# Limit to API-key providers in PROVIDER_REGISTRY — other provider
|
||||||
# types (OAuth, SDK, openrouter/anthropic/custom/auto) have their
|
# types (OAuth, SDK, anthropic/custom/auto) have their own env-var
|
||||||
# own env-var checks elsewhere in doctor, and get_auth_status()
|
# checks elsewhere in doctor, and get_auth_status() returns a bare
|
||||||
# returns a bare {logged_in: False} for anything it doesn't
|
# {logged_in: False} for anything it doesn't explicitly dispatch,
|
||||||
# explicitly dispatch, which would produce false positives.
|
# which would produce false positives.
|
||||||
if runtime_provider and runtime_provider not in {"auto", "custom", "openrouter"}:
|
if runtime_provider and runtime_provider not in ("auto", "custom"):
|
||||||
try:
|
try:
|
||||||
from hermes_cli.auth import PROVIDER_REGISTRY, get_auth_status
|
if runtime_provider == "openrouter":
|
||||||
pconfig = PROVIDER_REGISTRY.get(runtime_provider)
|
from hermes_cli.config import get_env_value
|
||||||
if pconfig and getattr(pconfig, "auth_type", "") == "api_key":
|
|
||||||
status = get_auth_status(runtime_provider) or {}
|
|
||||||
configured = bool(
|
configured = bool(
|
||||||
status.get("configured")
|
str(get_env_value("OPENROUTER_API_KEY") or "").strip()
|
||||||
or status.get("logged_in")
|
or str(get_env_value("OPENAI_API_KEY") or "").strip()
|
||||||
or status.get("api_key")
|
|
||||||
)
|
)
|
||||||
if not configured:
|
else:
|
||||||
check_fail(
|
from hermes_cli.auth import PROVIDER_REGISTRY, get_auth_status
|
||||||
f"model.provider '{runtime_provider}' is set but no API key is configured",
|
|
||||||
"(check ~/.hermes/.env or run 'hermes setup')",
|
pconfig = PROVIDER_REGISTRY.get(runtime_provider)
|
||||||
)
|
configured = True
|
||||||
issues.append(
|
if pconfig and getattr(pconfig, "auth_type", "") == "api_key":
|
||||||
f"No credentials found for provider '{runtime_provider}'. "
|
status = get_auth_status(runtime_provider) or {}
|
||||||
f"Run 'hermes setup' or set the provider's API key in {_DHH}/.env, "
|
configured = bool(
|
||||||
f"or switch providers with 'hermes config set model.provider <name>'"
|
status.get("configured")
|
||||||
|
or status.get("logged_in")
|
||||||
|
or status.get("api_key")
|
||||||
)
|
)
|
||||||
|
if not configured:
|
||||||
|
check_fail(
|
||||||
|
f"model.provider '{runtime_provider}' is set but no API key is configured",
|
||||||
|
"(check ~/.hermes/.env or run 'hermes setup')",
|
||||||
|
)
|
||||||
|
issues.append(
|
||||||
|
f"No credentials found for provider '{runtime_provider}'. "
|
||||||
|
f"Run 'hermes setup' or set the provider's API key in {_DHH}/.env, "
|
||||||
|
f"or switch providers with 'hermes config set model.provider <name>'"
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -477,6 +477,48 @@ def test_run_doctor_accepts_bare_custom_provider(monkeypatch, tmp_path):
|
|||||||
assert "model.provider 'custom' is not a recognised provider" not in out
|
assert "model.provider 'custom' is not a recognised provider" not in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_doctor_flags_missing_credentials_for_active_openrouter_provider(monkeypatch, tmp_path):
|
||||||
|
home = tmp_path / ".hermes"
|
||||||
|
home.mkdir(parents=True, exist_ok=True)
|
||||||
|
(home / "config.yaml").write_text(
|
||||||
|
"model:\n"
|
||||||
|
" provider: openrouter\n"
|
||||||
|
" default: openai/gpt-4.1-mini\n",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
monkeypatch.setattr(doctor_mod, "HERMES_HOME", home)
|
||||||
|
monkeypatch.setattr(doctor_mod, "PROJECT_ROOT", tmp_path / "project")
|
||||||
|
monkeypatch.setattr(doctor_mod, "_DHH", str(home))
|
||||||
|
(tmp_path / "project").mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
fake_model_tools = types.SimpleNamespace(
|
||||||
|
check_tool_availability=lambda *a, **kw: ([], []),
|
||||||
|
TOOLSET_REQUIREMENTS={},
|
||||||
|
)
|
||||||
|
monkeypatch.setitem(sys.modules, "model_tools", fake_model_tools)
|
||||||
|
monkeypatch.delenv("OPENROUTER_API_KEY", raising=False)
|
||||||
|
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from hermes_cli import auth as _auth_mod
|
||||||
|
|
||||||
|
monkeypatch.setattr(_auth_mod, "get_nous_auth_status", lambda: {})
|
||||||
|
monkeypatch.setattr(_auth_mod, "get_codex_auth_status", lambda: {})
|
||||||
|
monkeypatch.setattr(_auth_mod, "get_gemini_oauth_auth_status", lambda: {})
|
||||||
|
monkeypatch.setattr(_auth_mod, "get_minimax_oauth_auth_status", lambda: {})
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
buf = io.StringIO()
|
||||||
|
with contextlib.redirect_stdout(buf):
|
||||||
|
doctor_mod.run_doctor(Namespace(fix=False))
|
||||||
|
|
||||||
|
out = buf.getvalue()
|
||||||
|
assert "model.provider 'openrouter' is set but no API key is configured" in out
|
||||||
|
assert "No credentials found for provider 'openrouter'." in out
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("provider", "default_model"),
|
("provider", "default_model"),
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user