fix(model): include Premium+ in xAI OAuth label
X Premium+ also grants Grok OAuth access — the 'SuperGrok Subscription' wording suggested SuperGrok was the only entitlement path. Updated to 'SuperGrok / Premium+' across the picker label, setup wizard, auth flows, and docs so Premium+ subscribers know the row applies to them too.
This commit is contained in:
parent
4987fd2a59
commit
af144cd60d
@ -3260,7 +3260,7 @@ def resolve_provider_client(
|
|||||||
if client is None:
|
if client is None:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"resolve_provider_client: xai-oauth requested but no xAI "
|
"resolve_provider_client: xai-oauth requested but no xAI "
|
||||||
"OAuth token found (run: hermes model -> xAI Grok OAuth — SuperGrok Subscription)"
|
"OAuth token found (run: hermes model -> xAI Grok OAuth — SuperGrok / Premium+)"
|
||||||
)
|
)
|
||||||
return None, None
|
return None, None
|
||||||
final_model = _normalize_resolved_model(model or default, provider)
|
final_model = _normalize_resolved_model(model or default, provider)
|
||||||
|
|||||||
@ -2867,7 +2867,7 @@ def run_conversation(
|
|||||||
agent._vprint(f"{agent.log_prefix} 2. Then run `hermes auth` to re-authenticate.", force=True)
|
agent._vprint(f"{agent.log_prefix} 2. Then run `hermes auth` to re-authenticate.", force=True)
|
||||||
else:
|
else:
|
||||||
agent._vprint(f"{agent.log_prefix} 💡 xAI OAuth token was rejected (HTTP 401). To fix:", force=True)
|
agent._vprint(f"{agent.log_prefix} 💡 xAI OAuth token was rejected (HTTP 401). To fix:", force=True)
|
||||||
agent._vprint(f"{agent.log_prefix} re-authenticate with xAI Grok OAuth (SuperGrok Subscription) from `hermes model`.", force=True)
|
agent._vprint(f"{agent.log_prefix} re-authenticate with xAI Grok OAuth (SuperGrok / Premium+) from `hermes model`.", force=True)
|
||||||
else:
|
else:
|
||||||
agent._vprint(f"{agent.log_prefix} 💡 Your API key was rejected by the provider. Check:", force=True)
|
agent._vprint(f"{agent.log_prefix} 💡 Your API key was rejected by the provider. Check:", force=True)
|
||||||
agent._vprint(f"{agent.log_prefix} • Is the key valid? Run: hermes setup", force=True)
|
agent._vprint(f"{agent.log_prefix} • Is the key valid? Run: hermes setup", force=True)
|
||||||
|
|||||||
@ -285,7 +285,7 @@ def _remove_xai_oauth_loopback_pkce(provider: str, removed) -> RemovalResult:
|
|||||||
if _clear_auth_store_provider(provider):
|
if _clear_auth_store_provider(provider):
|
||||||
result.cleaned.append(f"Cleared {provider} OAuth tokens from auth store")
|
result.cleaned.append(f"Cleared {provider} OAuth tokens from auth store")
|
||||||
result.hints.append(
|
result.hints.append(
|
||||||
"Run `hermes model` → xAI Grok OAuth (SuperGrok Subscription) to re-authenticate if needed."
|
"Run `hermes model` → xAI Grok OAuth (SuperGrok / Premium+) to re-authenticate if needed."
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@ -198,7 +198,7 @@ PROVIDER_REGISTRY: Dict[str, ProviderConfig] = {
|
|||||||
),
|
),
|
||||||
"xai-oauth": ProviderConfig(
|
"xai-oauth": ProviderConfig(
|
||||||
id="xai-oauth",
|
id="xai-oauth",
|
||||||
name="xAI Grok OAuth (SuperGrok Subscription)",
|
name="xAI Grok OAuth (SuperGrok / Premium+)",
|
||||||
auth_type="oauth_external",
|
auth_type="oauth_external",
|
||||||
inference_base_url=DEFAULT_XAI_OAUTH_BASE_URL,
|
inference_base_url=DEFAULT_XAI_OAUTH_BASE_URL,
|
||||||
),
|
),
|
||||||
@ -3407,7 +3407,7 @@ def _read_xai_oauth_tokens(*, _lock: bool = True) -> Dict[str, Any]:
|
|||||||
state = _load_provider_state(auth_store, "xai-oauth")
|
state = _load_provider_state(auth_store, "xai-oauth")
|
||||||
if not state:
|
if not state:
|
||||||
raise AuthError(
|
raise AuthError(
|
||||||
"No xAI OAuth credentials stored. Select xAI Grok OAuth (SuperGrok Subscription) in `hermes model`.",
|
"No xAI OAuth credentials stored. Select xAI Grok OAuth (SuperGrok / Premium+) in `hermes model`.",
|
||||||
provider="xai-oauth",
|
provider="xai-oauth",
|
||||||
code="xai_auth_missing",
|
code="xai_auth_missing",
|
||||||
relogin_required=True,
|
relogin_required=True,
|
||||||
@ -6338,7 +6338,7 @@ def _login_xai_oauth(
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print("Signing in to xAI Grok OAuth (SuperGrok Subscription)...")
|
print("Signing in to xAI Grok OAuth (SuperGrok / Premium+)...")
|
||||||
print("(Hermes creates its own local OAuth session)")
|
print("(Hermes creates its own local OAuth session)")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|||||||
@ -3287,7 +3287,7 @@ def _model_flow_openai_codex(config, current_model=""):
|
|||||||
|
|
||||||
|
|
||||||
def _model_flow_xai_oauth(_config, current_model="", *, args=None):
|
def _model_flow_xai_oauth(_config, current_model="", *, args=None):
|
||||||
"""xAI Grok OAuth (SuperGrok Subscription) provider: ensure logged in, then pick model."""
|
"""xAI Grok OAuth (SuperGrok / Premium+) provider: ensure logged in, then pick model."""
|
||||||
from hermes_cli.auth import (
|
from hermes_cli.auth import (
|
||||||
get_xai_oauth_auth_status,
|
get_xai_oauth_auth_status,
|
||||||
_prompt_model_selection,
|
_prompt_model_selection,
|
||||||
@ -3302,7 +3302,7 @@ def _model_flow_xai_oauth(_config, current_model="", *, args=None):
|
|||||||
|
|
||||||
status = get_xai_oauth_auth_status()
|
status = get_xai_oauth_auth_status()
|
||||||
if status.get("logged_in"):
|
if status.get("logged_in"):
|
||||||
print(" xAI Grok OAuth (SuperGrok Subscription) credentials: ✓")
|
print(" xAI Grok OAuth (SuperGrok / Premium+) credentials: ✓")
|
||||||
print()
|
print()
|
||||||
print(" 1. Use existing credentials")
|
print(" 1. Use existing credentials")
|
||||||
print(" 2. Reauthenticate (new OAuth login)")
|
print(" 2. Reauthenticate (new OAuth login)")
|
||||||
@ -3340,7 +3340,7 @@ def _model_flow_xai_oauth(_config, current_model="", *, args=None):
|
|||||||
elif choice == "3":
|
elif choice == "3":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
print("Not logged into xAI Grok OAuth (SuperGrok Subscription). Starting login...")
|
print("Not logged into xAI Grok OAuth (SuperGrok / Premium+). Starting login...")
|
||||||
print()
|
print()
|
||||||
try:
|
try:
|
||||||
mock_args = argparse.Namespace(
|
mock_args = argparse.Namespace(
|
||||||
@ -3374,7 +3374,7 @@ def _model_flow_xai_oauth(_config, current_model="", *, args=None):
|
|||||||
if selected:
|
if selected:
|
||||||
_save_model_choice(selected)
|
_save_model_choice(selected)
|
||||||
_update_config_for_provider("xai-oauth", base_url)
|
_update_config_for_provider("xai-oauth", base_url)
|
||||||
print(f"Default model set to: {selected} (via xAI Grok OAuth — SuperGrok Subscription)")
|
print(f"Default model set to: {selected} (via xAI Grok OAuth — SuperGrok / Premium+)")
|
||||||
else:
|
else:
|
||||||
print("No change.")
|
print("No change.")
|
||||||
|
|
||||||
|
|||||||
@ -929,7 +929,7 @@ CANONICAL_PROVIDERS: list[ProviderEntry] = [
|
|||||||
ProviderEntry("anthropic", "Anthropic", "Anthropic (Claude models — API key or Claude Code)"),
|
ProviderEntry("anthropic", "Anthropic", "Anthropic (Claude models — API key or Claude Code)"),
|
||||||
ProviderEntry("openai-codex", "OpenAI Codex", "OpenAI Codex"),
|
ProviderEntry("openai-codex", "OpenAI Codex", "OpenAI Codex"),
|
||||||
ProviderEntry("alibaba", "Qwen Cloud", "Qwen Cloud / DashScope Coding (Qwen + multi-provider)"),
|
ProviderEntry("alibaba", "Qwen Cloud", "Qwen Cloud / DashScope Coding (Qwen + multi-provider)"),
|
||||||
ProviderEntry("xai-oauth", "xAI Grok OAuth (SuperGrok Subscription)", "xAI Grok OAuth (SuperGrok Subscription)"),
|
ProviderEntry("xai-oauth", "xAI Grok OAuth (SuperGrok / Premium+)", "xAI Grok OAuth (SuperGrok / Premium+)"),
|
||||||
ProviderEntry("xiaomi", "Xiaomi MiMo", "Xiaomi MiMo (MiMo-V2.5 and V2 models — pro, omni, flash)"),
|
ProviderEntry("xiaomi", "Xiaomi MiMo", "Xiaomi MiMo (MiMo-V2.5 and V2 models — pro, omni, flash)"),
|
||||||
ProviderEntry("tencent-tokenhub", "Tencent TokenHub", "Tencent TokenHub (Hy3 Preview — direct API via tokenhub.tencentmaas.com)"),
|
ProviderEntry("tencent-tokenhub", "Tencent TokenHub", "Tencent TokenHub (Hy3 Preview — direct API via tokenhub.tencentmaas.com)"),
|
||||||
ProviderEntry("nvidia", "NVIDIA NIM", "NVIDIA NIM (Nemotron models — build.nvidia.com or local NIM)"),
|
ProviderEntry("nvidia", "NVIDIA NIM", "NVIDIA NIM (Nemotron models — build.nvidia.com or local NIM)"),
|
||||||
@ -3491,7 +3491,7 @@ def validate_requested_model(
|
|||||||
suggestion_text = ""
|
suggestion_text = ""
|
||||||
if suggestions:
|
if suggestions:
|
||||||
suggestion_text = "\n Similar models: " + ", ".join(f"`{s}`" for s in suggestions)
|
suggestion_text = "\n Similar models: " + ", ".join(f"`{s}`" for s in suggestions)
|
||||||
provider_label = "OpenAI Codex" if normalized == "openai-codex" else "xAI Grok OAuth (SuperGrok Subscription)"
|
provider_label = "OpenAI Codex" if normalized == "openai-codex" else "xAI Grok OAuth (SuperGrok / Premium+)"
|
||||||
return {
|
return {
|
||||||
"accepted": True,
|
"accepted": True,
|
||||||
"persist": True,
|
"persist": True,
|
||||||
|
|||||||
@ -381,7 +381,7 @@ _LABEL_OVERRIDES: Dict[str, str] = {
|
|||||||
"local": "Local endpoint",
|
"local": "Local endpoint",
|
||||||
"bedrock": "AWS Bedrock",
|
"bedrock": "AWS Bedrock",
|
||||||
"ollama-cloud": "Ollama Cloud",
|
"ollama-cloud": "Ollama Cloud",
|
||||||
"xai-oauth": "xAI Grok OAuth (SuperGrok Subscription)",
|
"xai-oauth": "xAI Grok OAuth (SuperGrok / Premium+)",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1094,7 +1094,7 @@ def _xai_oauth_logged_in_for_setup() -> bool:
|
|||||||
"""True iff xAI Grok OAuth credentials are already stored locally.
|
"""True iff xAI Grok OAuth credentials are already stored locally.
|
||||||
|
|
||||||
Lets TTS / STT setup skip the API-key prompt for users who logged in
|
Lets TTS / STT setup skip the API-key prompt for users who logged in
|
||||||
through ``hermes model`` -> xAI Grok OAuth (SuperGrok Subscription).
|
through ``hermes model`` -> xAI Grok OAuth (SuperGrok / Premium+).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
from hermes_cli.auth import get_xai_oauth_auth_status
|
from hermes_cli.auth import get_xai_oauth_auth_status
|
||||||
@ -1124,7 +1124,7 @@ def _run_xai_oauth_login_from_setup() -> bool:
|
|||||||
|
|
||||||
open_browser = not _is_remote_session()
|
open_browser = not _is_remote_session()
|
||||||
print()
|
print()
|
||||||
print_info("Signing in to xAI Grok OAuth (SuperGrok Subscription)...")
|
print_info("Signing in to xAI Grok OAuth (SuperGrok / Premium+)...")
|
||||||
try:
|
try:
|
||||||
creds = _xai_oauth_loopback_login(open_browser=open_browser)
|
creds = _xai_oauth_loopback_login(open_browser=open_browser)
|
||||||
_save_xai_oauth_tokens(
|
_save_xai_oauth_tokens(
|
||||||
@ -1259,7 +1259,7 @@ def _setup_tts_provider(config: dict):
|
|||||||
|
|
||||||
if oauth_logged_in:
|
if oauth_logged_in:
|
||||||
print_success(
|
print_success(
|
||||||
"xAI TTS will use your xAI Grok OAuth (SuperGrok Subscription) "
|
"xAI TTS will use your xAI Grok OAuth (SuperGrok / Premium+) "
|
||||||
"credentials"
|
"credentials"
|
||||||
)
|
)
|
||||||
elif existing_api_key:
|
elif existing_api_key:
|
||||||
@ -1269,7 +1269,7 @@ def _setup_tts_provider(config: dict):
|
|||||||
choice_idx = prompt_choice(
|
choice_idx = prompt_choice(
|
||||||
"How do you want xAI TTS to authenticate?",
|
"How do you want xAI TTS to authenticate?",
|
||||||
choices=[
|
choices=[
|
||||||
"Sign in with xAI Grok OAuth (SuperGrok Subscription) — browser login",
|
"Sign in with xAI Grok OAuth (SuperGrok / Premium+) — browser login",
|
||||||
"Paste an xAI API key (console.x.ai)",
|
"Paste an xAI API key (console.x.ai)",
|
||||||
"Skip → fallback to Edge TTS",
|
"Skip → fallback to Edge TTS",
|
||||||
],
|
],
|
||||||
|
|||||||
@ -101,7 +101,7 @@ def _xai_credentials_present() -> bool:
|
|||||||
"""Cheap, side-effect-free check for usable xAI credentials.
|
"""Cheap, side-effect-free check for usable xAI credentials.
|
||||||
|
|
||||||
Used to auto-enable the ``x_search`` toolset when the user has either
|
Used to auto-enable the ``x_search`` toolset when the user has either
|
||||||
completed xAI Grok OAuth (SuperGrok subscription) or set
|
completed xAI Grok OAuth (SuperGrok / Premium+) or set
|
||||||
``XAI_API_KEY``. Does NOT hit the network — only inspects the local
|
``XAI_API_KEY``. Does NOT hit the network — only inspects the local
|
||||||
auth store and environment. The tool's runtime ``check_fn`` still
|
auth store and environment. The tool's runtime ``check_fn`` still
|
||||||
gates schema registration if creds later expire or get revoked.
|
gates schema registration if creds later expire or get revoked.
|
||||||
@ -356,7 +356,7 @@ TOOL_CATEGORIES = {
|
|||||||
"icon": "🐦",
|
"icon": "🐦",
|
||||||
"providers": [
|
"providers": [
|
||||||
{
|
{
|
||||||
"name": "xAI Grok OAuth (SuperGrok Subscription)",
|
"name": "xAI Grok OAuth (SuperGrok / Premium+)",
|
||||||
"badge": "subscription",
|
"badge": "subscription",
|
||||||
"tag": "Browser login at accounts.x.ai — no API key required",
|
"tag": "Browser login at accounts.x.ai — no API key required",
|
||||||
"env_vars": [],
|
"env_vars": [],
|
||||||
@ -1008,7 +1008,7 @@ def _run_post_setup(post_setup_key: str):
|
|||||||
|
|
||||||
if oauth_logged_in:
|
if oauth_logged_in:
|
||||||
_print_success(
|
_print_success(
|
||||||
" xAI will use your xAI Grok OAuth (SuperGrok Subscription) credentials"
|
" xAI will use your xAI Grok OAuth (SuperGrok / Premium+) credentials"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if existing_api_key:
|
if existing_api_key:
|
||||||
@ -1031,7 +1031,7 @@ def _run_post_setup(post_setup_key: str):
|
|||||||
idx = prompt_choice(
|
idx = prompt_choice(
|
||||||
" How do you want xAI to authenticate?",
|
" How do you want xAI to authenticate?",
|
||||||
choices=[
|
choices=[
|
||||||
"Sign in with xAI Grok OAuth (SuperGrok Subscription) — browser login",
|
"Sign in with xAI Grok OAuth (SuperGrok / Premium+) — browser login",
|
||||||
"Paste an xAI API key (console.x.ai)",
|
"Paste an xAI API key (console.x.ai)",
|
||||||
"Skip — configure later via `hermes auth add xai-oauth`",
|
"Skip — configure later via `hermes auth add xai-oauth`",
|
||||||
],
|
],
|
||||||
|
|||||||
@ -11,7 +11,7 @@ Originally salvaged from PR #10600 by @Jaaneek; reshaped into the
|
|||||||
generate-only surface.
|
generate-only surface.
|
||||||
|
|
||||||
Authentication: xAI Grok OAuth tokens (preferred — billed against the
|
Authentication: xAI Grok OAuth tokens (preferred — billed against the
|
||||||
user's SuperGrok subscription) or ``XAI_API_KEY``. Both routes are
|
user's SuperGrok or X Premium+ subscription) or ``XAI_API_KEY``. Both routes are
|
||||||
resolved through ``tools.xai_http.resolve_xai_http_credentials`` so a
|
resolved through ``tools.xai_http.resolve_xai_http_credentials`` so a
|
||||||
single login covers chat + TTS + image gen + video gen + transcription.
|
single login covers chat + TTS + image gen + video gen + transcription.
|
||||||
Output is an HTTPS URL from xAI's CDN; the gateway downloads and
|
Output is an HTTPS URL from xAI's CDN; the gateway downloads and
|
||||||
@ -216,7 +216,7 @@ class XAIVideoGenProvider(VideoGenProvider):
|
|||||||
# Auth resolution lives entirely in the shared ``xai_grok`` post_setup
|
# Auth resolution lives entirely in the shared ``xai_grok`` post_setup
|
||||||
# hook (``hermes_cli/tools_config.py``) so the picker doesn't blindly
|
# hook (``hermes_cli/tools_config.py``) so the picker doesn't blindly
|
||||||
# prompt for an API key when the user is already signed in via xAI
|
# prompt for an API key when the user is already signed in via xAI
|
||||||
# Grok OAuth (SuperGrok Subscription) — TTS / image gen / video gen
|
# Grok OAuth (SuperGrok / Premium+) — TTS / image gen / video gen
|
||||||
# all share the same credential resolver. The hook offers an
|
# all share the same credential resolver. The hook offers an
|
||||||
# OAuth-vs-API-key choice when neither is configured.
|
# OAuth-vs-API-key choice when neither is configured.
|
||||||
return {
|
return {
|
||||||
@ -295,7 +295,7 @@ class XAIVideoGenProvider(VideoGenProvider):
|
|||||||
return error_response(
|
return error_response(
|
||||||
error=(
|
error=(
|
||||||
"No xAI credentials found. Sign in via `hermes auth add xai-oauth` "
|
"No xAI credentials found. Sign in via `hermes auth add xai-oauth` "
|
||||||
"(SuperGrok subscription) or set XAI_API_KEY from "
|
"(SuperGrok / Premium+) or set XAI_API_KEY from "
|
||||||
"https://console.x.ai/."
|
"https://console.x.ai/."
|
||||||
),
|
),
|
||||||
error_type="auth_required",
|
error_type="auth_required",
|
||||||
|
|||||||
@ -7,8 +7,8 @@ from hermes_cli.providers import get_label
|
|||||||
def test_xai_oauth_provider_label_is_not_collapsed_to_api_key_label():
|
def test_xai_oauth_provider_label_is_not_collapsed_to_api_key_label():
|
||||||
"""The model picker must distinguish xAI API-key and OAuth providers."""
|
"""The model picker must distinguish xAI API-key and OAuth providers."""
|
||||||
assert get_label("xai") == "xAI"
|
assert get_label("xai") == "xAI"
|
||||||
assert get_label("xai-oauth") == "xAI Grok OAuth (SuperGrok Subscription)"
|
assert get_label("xai-oauth") == "xAI Grok OAuth (SuperGrok / Premium+)"
|
||||||
assert get_label("grok-oauth") == "xAI Grok OAuth (SuperGrok Subscription)"
|
assert get_label("grok-oauth") == "xAI Grok OAuth (SuperGrok / Premium+)"
|
||||||
|
|
||||||
|
|
||||||
def test_xai_oauth_provider_labels_match_canonical_model_labels():
|
def test_xai_oauth_provider_labels_match_canonical_model_labels():
|
||||||
|
|||||||
@ -30,7 +30,7 @@ You need at least one way to connect to an LLM. Use `hermes model` to switch pro
|
|||||||
| **MiniMax** | `MINIMAX_API_KEY` in `~/.hermes/.env` (provider: `minimax`) |
|
| **MiniMax** | `MINIMAX_API_KEY` in `~/.hermes/.env` (provider: `minimax`) |
|
||||||
| **MiniMax China** | `MINIMAX_CN_API_KEY` in `~/.hermes/.env` (provider: `minimax-cn`) |
|
| **MiniMax China** | `MINIMAX_CN_API_KEY` in `~/.hermes/.env` (provider: `minimax-cn`) |
|
||||||
| **xAI (Grok) — Responses API** | `XAI_API_KEY` in `~/.hermes/.env` (provider: `xai`) |
|
| **xAI (Grok) — Responses API** | `XAI_API_KEY` in `~/.hermes/.env` (provider: `xai`) |
|
||||||
| **xAI Grok OAuth (SuperGrok)** | `hermes model` → "xAI Grok OAuth (SuperGrok Subscription)" — browser login, no API key. See [guide](../guides/xai-grok-oauth.md) |
|
| **xAI Grok OAuth (SuperGrok)** | `hermes model` → "xAI Grok OAuth (SuperGrok / Premium+)" — browser login, no API key. See [guide](../guides/xai-grok-oauth.md) |
|
||||||
| **Qwen Cloud (Alibaba DashScope)** | `DASHSCOPE_API_KEY` in `~/.hermes/.env` (provider: `alibaba`) |
|
| **Qwen Cloud (Alibaba DashScope)** | `DASHSCOPE_API_KEY` in `~/.hermes/.env` (provider: `alibaba`) |
|
||||||
| **Alibaba Cloud (Coding Plan)** | `DASHSCOPE_API_KEY` (provider: `alibaba-coding-plan`, alias: `alibaba_coding`) — separate billing SKU, different endpoint |
|
| **Alibaba Cloud (Coding Plan)** | `DASHSCOPE_API_KEY` (provider: `alibaba-coding-plan`, alias: `alibaba_coding`) — separate billing SKU, different endpoint |
|
||||||
| **Kilo Code** | `KILOCODE_API_KEY` in `~/.hermes/.env` (provider: `kilocode`) |
|
| **Kilo Code** | `KILOCODE_API_KEY` in `~/.hermes/.env` (provider: `kilocode`) |
|
||||||
@ -266,7 +266,7 @@ When using the Z.AI / GLM provider, Hermes automatically probes multiple endpoin
|
|||||||
|
|
||||||
xAI is wired through the Responses API (`codex_responses` transport) for automatic reasoning support on Grok 4 models — no `reasoning_effort` parameter needed, the server reasons by default. Set `XAI_API_KEY` in `~/.hermes/.env` and pick xAI in `hermes model`, or drop `grok` as a shortcut into `/model grok-4-1-fast-reasoning`.
|
xAI is wired through the Responses API (`codex_responses` transport) for automatic reasoning support on Grok 4 models — no `reasoning_effort` parameter needed, the server reasons by default. Set `XAI_API_KEY` in `~/.hermes/.env` and pick xAI in `hermes model`, or drop `grok` as a shortcut into `/model grok-4-1-fast-reasoning`.
|
||||||
|
|
||||||
SuperGrok and X Premium+ subscribers can sign in with browser OAuth instead of using an API key — pick **xAI Grok OAuth (SuperGrok Subscription)** in `hermes model`, or run `hermes auth add xai-oauth`. The same OAuth bearer token is automatically reused by direct-to-xAI tools (TTS, image gen, video gen, transcription). See the [xAI Grok OAuth guide](../guides/xai-grok-oauth.md) for the full flow — and if Hermes runs on a remote host, also see [OAuth over SSH / Remote Hosts](../guides/oauth-over-ssh.md) for the required `ssh -L` tunnel.
|
SuperGrok and X Premium+ subscribers can sign in with browser OAuth instead of using an API key — pick **xAI Grok OAuth (SuperGrok / Premium+)** in `hermes model`, or run `hermes auth add xai-oauth`. The same OAuth bearer token is automatically reused by direct-to-xAI tools (TTS, image gen, video gen, transcription). See the [xAI Grok OAuth guide](../guides/xai-grok-oauth.md) for the full flow — and if Hermes runs on a remote host, also see [OAuth over SSH / Remote Hosts](../guides/oauth-over-ssh.md) for the required `ssh -L` tunnel.
|
||||||
|
|
||||||
When using xAI as a provider (any base URL containing `x.ai`), Hermes automatically enables prompt caching by sending the `x-grok-conv-id` header with every API request. This routes requests to the same server within a conversation session, allowing xAI's infrastructure to reuse cached system prompts and conversation history.
|
When using xAI as a provider (any base URL containing `x.ai`), Hermes automatically enables prompt caching by sending the `x-grok-conv-id` header with every API request. This routes requests to the same server within a conversation session, allowing xAI's infrastructure to reuse cached system prompts and conversation history.
|
||||||
|
|
||||||
|
|||||||
@ -217,7 +217,7 @@ The single `video_generate` tool covers both modalities — pass `image_url` to
|
|||||||
|
|
||||||
| Tool | Description | Requires environment |
|
| Tool | Description | Requires environment |
|
||||||
|------|-------------|----------------------|
|
|------|-------------|----------------------|
|
||||||
| `x_search` | Search X (Twitter) posts, profiles, and threads using xAI's built-in `x_search` Responses tool. Use this for current discussion, reactions, or claims on X rather than general web pages. Off by default — opt in via `hermes tools` → 🐦 X (Twitter) Search. Schema is only registered when xAI credentials are configured (check_fn-gated). | XAI_API_KEY **or** xAI Grok OAuth (SuperGrok Subscription) login |
|
| `x_search` | Search X (Twitter) posts, profiles, and threads using xAI's built-in `x_search` Responses tool. Use this for current discussion, reactions, or claims on X rather than general web pages. Off by default — opt in via `hermes tools` → 🐦 X (Twitter) Search. Schema is only registered when xAI credentials are configured (check_fn-gated). | XAI_API_KEY **or** xAI Grok OAuth (SuperGrok / Premium+) login |
|
||||||
|
|
||||||
## `tts` toolset
|
## `tts` toolset
|
||||||
|
|
||||||
|
|||||||
@ -836,7 +836,7 @@ Available providers for auxiliary tasks: `auto`, `main`, plus any provider in th
|
|||||||
:::
|
:::
|
||||||
|
|
||||||
:::tip xAI Grok OAuth
|
:::tip xAI Grok OAuth
|
||||||
`xai-oauth` logs in via browser OAuth for SuperGrok and X Premium+ subscribers (no API key needed). Run `hermes model` and select **xAI Grok OAuth (SuperGrok Subscription)** to authenticate. The same OAuth token is reused for every direct-to-xAI surface (chat, auxiliary tasks, TTS, image gen, video gen, transcription). See the [xAI Grok OAuth guide](../guides/xai-grok-oauth.md), and if Hermes is on a remote host see [OAuth over SSH / Remote Hosts](../guides/oauth-over-ssh.md).
|
`xai-oauth` logs in via browser OAuth for SuperGrok and X Premium+ subscribers (no API key needed). Run `hermes model` and select **xAI Grok OAuth (SuperGrok / Premium+)** to authenticate. The same OAuth token is reused for every direct-to-xAI surface (chat, auxiliary tasks, TTS, image gen, video gen, transcription). See the [xAI Grok OAuth guide](../guides/xai-grok-oauth.md), and if Hermes is on a remote host see [OAuth over SSH / Remote Hosts](../guides/oauth-over-ssh.md).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::warning `"main"` is for auxiliary tasks only
|
:::warning `"main"` is for auxiliary tasks only
|
||||||
@ -962,7 +962,7 @@ These options apply to **auxiliary task configs** (`auxiliary:`, `compression:`,
|
|||||||
| `"nous"` | Force Nous Portal | `hermes auth` |
|
| `"nous"` | Force Nous Portal | `hermes auth` |
|
||||||
| `"codex"` | Force Codex OAuth (ChatGPT account). Supports vision (gpt-5.3-codex). | `hermes model` → Codex |
|
| `"codex"` | Force Codex OAuth (ChatGPT account). Supports vision (gpt-5.3-codex). | `hermes model` → Codex |
|
||||||
| `"minimax-oauth"` | Force MiniMax OAuth (browser login, no API key). Uses MiniMax-M2.7-highspeed for auxiliary tasks. | `hermes model` → MiniMax (OAuth) |
|
| `"minimax-oauth"` | Force MiniMax OAuth (browser login, no API key). Uses MiniMax-M2.7-highspeed for auxiliary tasks. | `hermes model` → MiniMax (OAuth) |
|
||||||
| `"xai-oauth"` | Force xAI Grok OAuth (browser login for SuperGrok or X Premium+ subscribers, no API key). Same OAuth token covers chat, TTS, image, video, and transcription. | `hermes model` → xAI Grok OAuth (SuperGrok Subscription) |
|
| `"xai-oauth"` | Force xAI Grok OAuth (browser login for SuperGrok or X Premium+ subscribers, no API key). Same OAuth token covers chat, TTS, image, video, and transcription. | `hermes model` → xAI Grok OAuth (SuperGrok / Premium+) |
|
||||||
| `"main"` | Use your active custom/main endpoint. This can come from `OPENAI_BASE_URL` + `OPENAI_API_KEY` or from a custom endpoint saved via `hermes model` / `config.yaml`. Works with OpenAI, local models, or any OpenAI-compatible API. **Auxiliary tasks only — not valid for `model.provider`.** | Custom endpoint credentials + base URL |
|
| `"main"` | Use your active custom/main endpoint. This can come from `OPENAI_BASE_URL` + `OPENAI_API_KEY` or from a custom endpoint saved via `hermes model` / `config.yaml`. Works with OpenAI, local models, or any OpenAI-compatible API. **Auxiliary tasks only — not valid for `model.provider`.** | Custom endpoint credentials + base URL |
|
||||||
|
|
||||||
Direct API-key providers from the main provider catalog also work here when you want side tasks to bypass your default router. `gmi` is valid once `GMI_API_KEY` is configured:
|
Direct API-key providers from the main provider catalog also work here when you want side tasks to bypass your default router. `gmi` is valid once `GMI_API_KEY` is configured:
|
||||||
|
|||||||
@ -35,7 +35,7 @@ hermes tools
|
|||||||
|
|
||||||
The picker offers two credential choices:
|
The picker offers two credential choices:
|
||||||
|
|
||||||
1. **xAI Grok OAuth (SuperGrok Subscription)** — opens the browser to `accounts.x.ai` if you're not already logged in
|
1. **xAI Grok OAuth (SuperGrok / Premium+)** — opens the browser to `accounts.x.ai` if you're not already logged in
|
||||||
2. **xAI API key** — prompts for `XAI_API_KEY`
|
2. **xAI API key** — prompts for `XAI_API_KEY`
|
||||||
|
|
||||||
Either choice satisfies the gating. You can pick whichever credentials you already have; the tool works identically with both. If both end up configured, OAuth is preferred at call time.
|
Either choice satisfies the gating. You can pick whichever credentials you already have; the tool works identically with both. If both end up configured, OAuth is preferred at call time.
|
||||||
@ -135,6 +135,6 @@ Causes worth checking:
|
|||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- [xAI Grok OAuth (SuperGrok Subscription)](../../guides/xai-grok-oauth.md) — the OAuth setup guide
|
- [xAI Grok OAuth (SuperGrok / Premium+)](../../guides/xai-grok-oauth.md) — the OAuth setup guide
|
||||||
- [Web Search & Extract](web-search.md) — for general (non-X) web search
|
- [Web Search & Extract](web-search.md) — for general (non-X) web search
|
||||||
- [Tools Reference](../../reference/tools-reference.md) — full tool catalog
|
- [Tools Reference](../../reference/tools-reference.md) — full tool catalog
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user