mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-05 07:41:39 +00:00
feat(xai-oauth): add xAI Grok OAuth (SuperGrok Subscription) provider — port to extracted modules
Original commit b62c99797 by Jaaneek targeted six locations in
pre-refactor run_agent.py. Re-applied to the extracted post-PR locations:
- api_mode dispatch → agent/agent_init.py
- is_xai_responses build_api_kwargs → agent/chat_completion_helpers.py
- codex_auth_retry block + 401 hint → agent/conversation_loop.py
- _try_refresh_codex_client_credentials body → run_agent.py (kept)
The non-run_agent.py portions of the commit (auxiliary_client, codex
transport, hermes_cli/auth, tools/xai_http, tests, docs) merged cleanly
from main via the prior merge commit.
Co-authored-by: Jaaneek <Jaaneek@users.noreply.github.com>
This commit is contained in:
parent
7d221aa1f2
commit
b07524e53a
4 changed files with 64 additions and 14 deletions
55
run_agent.py
55
run_agent.py
|
|
@ -2449,15 +2449,60 @@ class AIAgent:
|
|||
return run_codex_create_stream_fallback(self, api_kwargs, client)
|
||||
|
||||
def _try_refresh_codex_client_credentials(self, *, force: bool = True) -> bool:
|
||||
if self.api_mode != "codex_responses" or self.provider != "openai-codex":
|
||||
if self.api_mode != "codex_responses" or self.provider not in {"openai-codex", "xai-oauth"}:
|
||||
return False
|
||||
|
||||
# Guard against silent account swap.
|
||||
#
|
||||
# When an agent is using a non-singleton credential — e.g. a manual
|
||||
# pool entry (``hermes auth add xai-oauth``) whose tokens belong to
|
||||
# a different account than the loopback_pkce singleton, or an agent
|
||||
# constructed with an explicit ``api_key=`` arg — force-refreshing
|
||||
# the singleton here and adopting its tokens silently re-routes the
|
||||
# rest of the conversation onto the singleton's account. The
|
||||
# credential pool's reactive recovery (``_recover_with_credential_pool``)
|
||||
# is the right channel for that case; this path is the
|
||||
# singleton-only fallback used when the pool can't recover, and
|
||||
# MUST only fire when the agent really is on singleton tokens.
|
||||
try:
|
||||
if self.provider == "openai-codex":
|
||||
from hermes_cli.auth import resolve_codex_runtime_credentials
|
||||
|
||||
singleton_now = resolve_codex_runtime_credentials(
|
||||
refresh_if_expiring=False,
|
||||
)
|
||||
else:
|
||||
from hermes_cli.auth import resolve_xai_oauth_runtime_credentials
|
||||
|
||||
singleton_now = resolve_xai_oauth_runtime_credentials(
|
||||
refresh_if_expiring=False,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.debug("%s singleton read failed: %s", self.provider, exc)
|
||||
return False
|
||||
|
||||
singleton_key = str(singleton_now.get("api_key") or "").strip()
|
||||
active_key = str(self.api_key or "").strip()
|
||||
if singleton_key and active_key and singleton_key != active_key:
|
||||
logger.debug(
|
||||
"%s singleton tokens differ from the active api_key; "
|
||||
"skipping singleton force-refresh to avoid silent account swap. "
|
||||
"Reactive credential rotation should go through the pool.",
|
||||
self.provider,
|
||||
)
|
||||
return False
|
||||
|
||||
try:
|
||||
from hermes_cli.auth import resolve_codex_runtime_credentials
|
||||
if self.provider == "openai-codex":
|
||||
from hermes_cli.auth import resolve_codex_runtime_credentials
|
||||
|
||||
creds = resolve_codex_runtime_credentials(force_refresh=force)
|
||||
creds = resolve_codex_runtime_credentials(force_refresh=force)
|
||||
else:
|
||||
from hermes_cli.auth import resolve_xai_oauth_runtime_credentials
|
||||
|
||||
creds = resolve_xai_oauth_runtime_credentials(force_refresh=force)
|
||||
except Exception as exc:
|
||||
logger.debug("Codex credential refresh failed: %s", exc)
|
||||
logger.debug("%s credential refresh failed: %s", self.provider, exc)
|
||||
return False
|
||||
|
||||
api_key = creds.get("api_key")
|
||||
|
|
@ -2472,7 +2517,7 @@ class AIAgent:
|
|||
self._client_kwargs["api_key"] = self.api_key
|
||||
self._client_kwargs["base_url"] = self.base_url
|
||||
|
||||
if not self._replace_primary_openai_client(reason="codex_credential_refresh"):
|
||||
if not self._replace_primary_openai_client(reason=f"{self.provider}_credential_refresh"):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue