fix(usage): preserve routed profile context in Nous account fetches

(cherry picked from commit 1675c92c8b0101315a9e18823a7c2e444be29259)
This commit is contained in:
NanPan
2026-09-16 17:55:21 +08:00
committed by Teknium
parent 5ad9ee8630
commit f1b7ae7206
3 changed files with 52 additions and 2 deletions

View File

@@ -186,9 +186,11 @@ def _nous_logged_in() -> bool:
def _fetch_portal_account(timeout: float):
"""Wall-clock-bounded fresh portal account fetch (raises on any failure/timeout)."""
import concurrent.futures
import contextvars
from hermes_cli.nous_account import get_nous_portal_account_info
context = contextvars.copy_context()
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
return pool.submit(get_nous_portal_account_info, force_fresh=True).result(timeout=timeout)
return pool.submit(context.run, get_nous_portal_account_info, force_fresh=True).result(timeout=timeout)
def nous_credits_lines(*, markdown: bool = False, timeout: float = 10.0) -> list[str]:

View File

@@ -49,9 +49,11 @@ def nous_logged_in() -> bool:
def fetch_nous_account(timeout: float):
"""Wall-clock-bounded fresh portal account fetch. Raises on failure/timeout."""
import concurrent.futures
import contextvars
from hermes_cli.nous_account import get_nous_portal_account_info
context = contextvars.copy_context()
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
return pool.submit(get_nous_portal_account_info, force_fresh=True).result(timeout=timeout)
return pool.submit(context.run, get_nous_portal_account_info, force_fresh=True).result(timeout=timeout)
def format_renews(value: Optional[str]) -> Optional[str]:

View File

@@ -0,0 +1,46 @@
from pathlib import Path
import pytest
from agent import account_usage, billing_usage
from hermes_constants import (
get_hermes_home,
reset_hermes_home_override,
set_hermes_home_override,
)
@pytest.mark.parametrize(
"fetcher",
[account_usage._fetch_portal_account, billing_usage.fetch_nous_account],
)
def test_nous_account_fetch_preserves_profile_home_in_timeout_worker(
monkeypatch, tmp_path: Path, fetcher
):
"""The bounded account fetch must read auth from the routed profile, not the launch profile."""
launch_home = tmp_path / "launch"
profile_home = tmp_path / "profiles" / "secondary"
launch_home.mkdir()
profile_home.mkdir(parents=True)
monkeypatch.setenv("HERMES_HOME", str(launch_home))
observed_homes: list[Path] = []
def fake_account_fetch(*, force_fresh: bool = False):
assert force_fresh is True
observed_homes.append(get_hermes_home())
return observed_homes[-1]
monkeypatch.setattr(
"hermes_cli.nous_account.get_nous_portal_account_info",
fake_account_fetch,
)
token = set_hermes_home_override(profile_home)
try:
assert get_hermes_home() == profile_home
assert fetcher(1.0) == profile_home
finally:
reset_hermes_home_override(token)
assert observed_homes == [profile_home]