perf(providers): invalidate cache on oauth credential changes

This commit is contained in:
seanxgao committed 2026-07-13 19:58:41 +08:00
1 parent b1867d7bf4
commit ab4d64f157
3 files changed
+41 -17

No files matched your search

+20 -17
View File
@@ -218,6 +218,23 @@ def _now_iso() -> str:
return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
def _invalidate_provider_state_caches(provider: str) -> None:
"""Invalidate caches derived from provider credential state."""
try:
from api.config import invalidate_credential_pool_cache
invalidate_credential_pool_cache(provider)
except Exception:
logger.debug("Failed to invalidate %s credential cache", provider, exc_info=True)
try:
from api.providers import invalidate_providers_cache
invalidate_providers_cache()
except Exception:
logger.debug("Failed to invalidate providers cache after %s credential change", provider, exc_info=True)
def _persist_codex_credentials(hermes_home: Path, token_data: dict[str, Any]) -> Path:
"""Persist Codex OAuth credentials to active-profile auth.json."""
access_token = str(token_data.get("access_token") or "").strip()
@@ -277,12 +294,7 @@ def _persist_codex_credentials(hermes_home: Path, token_data: dict[str, Any]) ->
auth["updated_at"] = now
path = _write_auth_json(auth, auth_path)
try:
from api.config import invalidate_credential_pool_cache
invalidate_credential_pool_cache("openai-codex")
except Exception:
logger.debug("Failed to invalidate openai-codex credential cache", exc_info=True)
_invalidate_provider_state_caches("openai-codex")
return path
@@ -389,12 +401,7 @@ def _link_anthropic_credentials(hermes_home: Path) -> None:
})
auth["updated_at"] = now
_write_auth_json(auth, auth_path)
try:
from api.config import invalidate_credential_pool_cache
invalidate_credential_pool_cache("anthropic")
except Exception:
logger.debug("Failed to invalidate anthropic credential cache", exc_info=True)
_invalidate_provider_state_caches("anthropic")
def _anthropic_public_start_payload(flow_id: str, flow: dict[str, Any]) -> dict[str, Any]:
@@ -515,11 +522,7 @@ def _remove_anthropic_link_marker(hermes_home: Path) -> None:
pool.pop("anthropic", None)
auth["updated_at"] = _now_iso()
_write_auth_json(auth, auth_path)
try:
from api.config import invalidate_credential_pool_cache
invalidate_credential_pool_cache("anthropic")
except Exception:
logger.debug("Failed to invalidate anthropic credential cache", exc_info=True)
_invalidate_provider_state_caches("anthropic")
# ── Codex protocol ──────────────────────────────────────────────────────────
+3
View File
@@ -1025,6 +1025,9 @@ def _get_cached_providers(cache_key: tuple[Any, ...]) -> dict[str, Any] | None:
def _store_cached_providers(cache_key: tuple[Any, ...], payload: dict[str, Any]) -> dict[str, Any]:
with _providers_cache_lock:
# Single-entry by design: /api/providers is cacheable only for the
# active profile/config snapshot, so clear older snapshots to avoid
# retaining unbounded provider metadata across profile switches.
_providers_cache.clear()
_providers_cache[cache_key] = (time.monotonic(), copy.deepcopy(payload))
return payload
+18
View File
@@ -170,6 +170,24 @@ class TestGetProviders:
if hasattr(prov, "invalidate_providers_cache"):
prov.invalidate_providers_cache()
def test_oauth_credential_updates_invalidate_providers_cache(self, monkeypatch, tmp_path):
"""OAuth credential updates should invalidate cached Providers responses (#6010)."""
from api import oauth
from api import providers as prov
invalidated_credentials = []
providers_invalidated = []
monkeypatch.setattr(config, "invalidate_credential_pool_cache", invalidated_credentials.append)
monkeypatch.setattr(prov, "invalidate_providers_cache", lambda: providers_invalidated.append(True))
oauth._persist_codex_credentials(
tmp_path,
{"access_token": "access-token", "refresh_token": "refresh-token"},
)
assert invalidated_credentials == ["openai-codex"]
assert providers_invalidated == [True]
def test_returns_list_of_known_providers(self, monkeypatch, tmp_path):
"""GET /api/providers should return a list of all known providers."""
_install_fake_hermes_cli(monkeypatch)