diff --git a/hermes_cli/web_routers/models.py b/hermes_cli/web_routers/models.py index 1ba5328032..f7e12c0171 100644 --- a/hermes_cli/web_routers/models.py +++ b/hermes_cli/web_routers/models.py @@ -186,7 +186,11 @@ def get_recommended_default_model(provider: str = "", profile: Optional[str] = N if slug == "nous": try: - return _nous_recommended_default() + # The tier, Portal URL and recommendation caches are all per profile home. + with _config_profile_scope(profile): + return _nous_recommended_default() + except HTTPException: + raise # an unknown ?profile= is the scope's 404, not an empty recommendation except Exception: _log.exception("GET /api/model/recommended-default (nous) failed") return {"provider": "nous", "model": "", "free_tier": None} diff --git a/tests/hermes_cli/test_web_recommended_default_profile.py b/tests/hermes_cli/test_web_recommended_default_profile.py new file mode 100644 index 0000000000..1e92ec1e28 --- /dev/null +++ b/tests/hermes_cli/test_web_recommended_default_profile.py @@ -0,0 +1,54 @@ +"""``GET /api/model/recommended-default?provider=nous`` answers for the requested profile. + +The Nous branch returned before the route entered the profile scope, so ``?profile=b`` got the +tier read, Portal URL and caches of the profile that launched the dashboard, and an unknown +profile answered 200 instead of the scope's 404. Only the Portal account read is stubbed. +""" + +from types import SimpleNamespace + +import pytest + +pytest.importorskip("fastapi") +from fastapi.testclient import TestClient # noqa: E402 + + +@pytest.fixture() +def client(tmp_path, monkeypatch): + monkeypatch.setenv("HERMES_HOME", str(tmp_path)) + from hermes_cli import profiles as profiles_mod + + freebie = profiles_mod.get_profile_dir("freebie") + freebie.mkdir(parents=True, exist_ok=True) + (freebie / "config.yaml").write_text("model: {}\n", encoding="utf-8") + + from hermes_constants import get_hermes_home + import hermes_cli.nous_account as nous_account + + # The launch profile's account is paid, the "freebie" profile's is free tier. + monkeypatch.setattr(nous_account, "get_nous_portal_account_info", lambda **_k: SimpleNamespace( + is_free_tier=get_hermes_home().name == "freebie")) + + from hermes_cli import web_server + + with TestClient(web_server.app, raise_server_exceptions=False) as c: + c.headers["Authorization"] = f"Bearer {web_server._SESSION_TOKEN}" + yield c + + +def test_nous_recommendation_reads_the_requested_profile(client): + launch = client.get("/api/model/recommended-default", params={"provider": "nous"}) + named = client.get("/api/model/recommended-default", + params={"provider": "nous", "profile": "freebie"}) + + assert launch.status_code == named.status_code == 200 + assert launch.json()["free_tier"] is False + assert named.json()["free_tier"] is True + + +def test_nous_recommendation_unknown_profile_is_404(client): + resp = client.get("/api/model/recommended-default", + params={"provider": "nous", "profile": "no-such-profile"}) + + assert resp.status_code == 404, resp.text + assert "no-such-profile" in resp.json()["detail"]