mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-08-13 17:16:12 +00:00
Follow-ups from review of #80590: - oauth.py: extract _rotate_and_persist() — the twin ~18-line OAuthRefreshError permanent/transient handling blocks in ensure_fresh_token and force_refresh_token were byte-identical except the log verb. - oauth.py: cap the exchange cycle at _REFRESH_TOTAL_BUDGET_SECONDS (20s). The retry runs while holding the global refresh locks on the path to a memory call; a timed-out first attempt no longer earns a second full 15s exchange (~32s lock hold -> <=20s). - oauth.py: transient-failure cooldown (_refresh_failure_at, 30s). Waiting threads and later turns fail open to the stale token instead of serializing their own full exchange cycles against an endpoint that just failed. Cleared on successful rotation and re-login. - oauth.py: mtime-gate reauth_required()'s config read — the dead-grant state persists until re-login, and the verdict can only change when the config file is rewritten; drop the per-call read+parse. - oauth.py: derive _TOKEN_VALUE_RE from ACCESS_TOKEN_PREFIX / REFRESH_TOKEN_PREFIX so a prefix change can't silently break redaction; promote redact_tokens to public (session.py imported the private name). - session.py: fast path in _reauth_required — skip config-path resolution entirely while no grant is dead (runs before every SDK call). - session.py: client-generation counter closes the fetch/store race in _sdk_session/_get_or_create_peer — an object resolved from the old client mid-rebuild is no longer cached (it would 401 forever and burn a token rotation per retry). - __init__.py: drop the getattr/callable/except triple-guard in _pop_auth_notice; the manager is always None or HonchoSessionManager. 7 new tests (budget, cooldown x3, generation guard, fast path); all mutation-checked (disabling each guard fails its test). honcho_plugin 293 passed; plugins/memory 285 passed; live E2E against a real HTTP token endpoint re-verified.