feat(providers): add native xAI provider#7050
Conversation
xAI is listed in models.dev (`id: xai`, `env: [XAI_API_KEY]`) but without
an `api` field, so `get_provider("xai")` returned a ProviderDef with
an empty base_url. Users had to configure xAI via `provider: custom`
and manually set `base_url: https://api.x.ai/v1`, losing the ergonomics
of a first-class provider (no `hermes model --provider xai`, no
auto-detection from `XAI_API_KEY`, no label, etc.).
Add xAI as a native api_key provider alongside zai, kimi-coding, minimax,
deepseek, and friends:
- `hermes_cli/auth.py` — register PROVIDER_REGISTRY["xai"] with
inference_base_url=https://api.x.ai/v1, api_key_env_vars=(XAI_API_KEY,),
base_url_env_var=XAI_BASE_URL.
- `hermes_cli/providers.py` — add HERMES_OVERLAYS["xai"] with
base_url_override, register `x-ai` and `x.ai` as aliases, and add
"xAI" to the LABELS dict.
- `hermes_cli/models.py` — populate _PROVIDER_MODELS["xai"] with the
11 public Grok text models (grok-4.20-*, grok-4-1-fast-*, grok-4-fast-*,
grok-4, grok-4-0709, grok-code-fast-1, grok-3, grok-3-mini) so that
`hermes model --provider xai` and `curated_models_for_provider("xai")`
return a usable catalog.
- `agent/model_metadata.py` — add `api.x.ai` to _URL_TO_PROVIDER so that
users who keep the legacy `provider: custom` + `base_url: https://api.x.ai/v1`
configuration still get correct context-length resolution via models.dev
(`_infer_provider_from_url` resolves to "xai" and lookup_models_dev_context
returns the real 2M/256k/131k values per model).
- Tests: add `xai` to the existing TestProviderRegistry.test_provider_registered
parametrize, and add a dedicated test_xai_env_vars assertion pinning
the env var names and default base URL.
After this change, users on xAI direct can configure:
model:
default: grok-4.20-0309-reasoning
provider: xai
instead of the current workaround:
model:
default: grok-4.20-0309-reasoning
provider: custom
base_url: https://api.x.ai/v1
Auto-detection from XAI_API_KEY, `hermes model` catalog listing, and
credential-pool integration all work as they do for the other api_key
providers. Complements the existing xAI integration (`x-grok-conv-id`
prompt caching, `"grok"` in TOOL_USE_ENFORCEMENT_MODELS) and
the context-length fallbacks in NousResearch#7039. Supersedes the earlier draft
PR NousResearch#6238 which proposed a narrower and incomplete fix.
21/21 tests pass on TestProviderRegistry.
9cc477e to
703e676
Compare
The auxiliary client resolution chain (compression, session_search,
vision, web_extract, etc.) had no direct xAI support. Users with
XAI_API_KEY had to rely on either the main provider fallback
(only if they were also on xAI as main) or routing through OpenRouter,
which defeats the purpose of using xAI direct for cheap/fast side tasks.
In particular, the vision auto-detection order was limited to OpenRouter
and Nous, meaning users with both XAI_API_KEY and OPENROUTER_API_KEY
saw every vision analysis routed through OpenRouter even if their main
provider was xai — burning OpenRouter credits and adding latency while
ignoring Grok 4's native vision support.
Add xAI as a first-class auxiliary backend:
- `_try_xai()` — new helper following the same pattern as `_try_openrouter()`
and `_try_nous()`. Reads the credential pool first, then falls back to
`XAI_API_KEY`. Returns a default model that is both vision-capable and
cheap: `grok-4-1-fast-non-reasoning` (text+image input, fast, ~$0.20/$0.50
per M tokens, no reasoning overhead — ideal for side tasks).
- `_XAI_DEFAULT_BASE_URL` and `_XAI_AUX_MODEL` constants next to the
existing `_NOUS_*` and `_ANTHROPIC_*` constants.
- `_PROVIDER_ALIASES` gains `x-ai` and `x.ai` -> `xai` so users can
spell the provider any of the three common ways.
- `_API_KEY_PROVIDER_AUX_MODELS["xai"] = "grok-4-1-fast-non-reasoning"`
so the api-key provider fallback path picks the same default.
- `resolve_provider_client("xai")` gets an explicit case so text
auxiliary tasks with `provider: xai` work without depending on
the PROVIDER_REGISTRY lookup (PR NousResearch#7050 adds the registry entry too,
but this PR stands alone).
- `_VISION_AUTO_PROVIDER_ORDER` gains `"xai"` at the end so users
without OpenRouter or Nous get xAI vision automatically. Back-compat
preserved for users who have OpenRouter — they keep the current behavior.
- `_resolve_strict_vision_backend("xai")` gets the matching case so
explicit `auxiliary.vision.provider: xai` in config.yaml resolves to
the xAI backend (no silent OpenRouter override).
Tests (4 new):
- test_explicit_xai — resolve_provider_client("xai") picks up
XAI_API_KEY and returns the default aux model.
- test_explicit_xai_alias_x_ai — the x-ai alias normalises to xai.
- test_vision_uses_xai_when_no_openrouter_no_nous — vision auto chain
falls back to xAI when nothing else is available.
- test_vision_forced_xai_uses_xai_backend — explicit config override
routes vision to xAI even when OpenRouter is available. Verifies the
api.x.ai base URL is used (not OpenRouter).
100/100 tests pass on tests/agent/test_auxiliary_client.py.
Complements the existing xAI integration (x-grok-conv-id prompt caching,
"grok" in TOOL_USE_ENFORCEMENT_MODELS) and the native provider
registration in NousResearch#7050 / context length fallbacks in NousResearch#7039.
|
Following up on @teknium1's note in #7039 about xAI working on their own native provider PR — happy to defer to that if it's imminent. Otherwise available to rebase/revise this as needed. If the bigger provider registration (PROVIDER_REGISTRY / HERMES_OVERLAYS / catalog / labels) is going to come from xAI directly, I can also close this and re-open as a minimal PR that keeps just the |
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes #7050
|
Merged via #7372. Your xAI provider implementation was cherry-picked with authorship preserved — clean, well-structured, follows existing patterns perfectly. Thanks, @Julientalbot! |
|
@teknium1, I'm currently building a business around Hermes Agent : I install, configure and monitor it for my clients. I already have 10+ clients with live Hermes Agents deployed, and I'm getting a lot of real-world feedback on what works well and what could be improved. I'd love to speak with someone from the Nous Research / Hermes team to share these insights. I believe my feedback could be genuinely valuable as I'm seeing daily usage at scale. Would it be possible to hop on a quick call or chat with one of you? Thanks in advance! |
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Adds xAI as a first-class provider: ProviderConfig in auth.py, HermesOverlay in providers.py, 11 curated Grok models, URL mapping in model_metadata.py, aliases (x-ai, x.ai), and env var tests. Uses standard OpenAI-compatible chat completions. Closes NousResearch#7050
Problem
xAI is listed in models.dev (
id: xai,env: [XAI_API_KEY]) but without anapifield. As a result,get_provider('xai')inhermes_cli/providers.pyreturns aProviderDefwith an emptybase_url, and xAI is absent fromPROVIDER_REGISTRYinhermes_cli/auth.pyand from_PROVIDER_MODELSinhermes_cli/models.py.Users pointing at xAI direct have to work around this with a
customprovider:This loses the ergonomics of a first-class provider:
hermes model --provider xaicatalog listingXAI_API_KEY(has to rely onOPENAI_API_KEYfallback insideprovider: custom)x-ai/x.ai_infer_provider_from_urlcan't resolve context length via models.dev for the legacy custom-endpoint configuration)Solution
Add xAI as a native api_key provider, following the same pattern as
zai,kimi-coding,minimax,deepseek,alibabaand friends.hermes_cli/auth.pyRegister
PROVIDER_REGISTRY['xai']:hermes_cli/providers.pyAdd
HERMES_OVERLAYS['xai']withbase_url_override(since models.dev doesn't provide one), registerx-ai/x.aias aliases, and addxAIto theLABELSdict.hermes_cli/models.pyPopulate
_PROVIDER_MODELS['xai']with the 11 public Grok text models sohermes model --provider xaiandcurated_models_for_provider('xai')return a usable catalog:(
grok-2-*andgrok-*-visionexcluded from the curated list — older / image-only.)agent/model_metadata.pyAdd
api.x.aito_URL_TO_PROVIDERso that users who keep the legacyprovider: custom+base_url: https://api.x.ai/v1configuration still get correct context-length resolution via models.dev (_infer_provider_from_urlresolves toxaiandlookup_models_dev_contextreturns the real 2M/256k/131k values per model).Usage after this change
No
base_urlneeded.XAI_API_KEYis auto-detected. The provider integrates with the existing credential pool, banner,hermes modellisting, and status output like any other native provider.The legacy
provider: custom+base_url: https://api.x.ai/v1configuration also keeps working, and now benefits from correct context-length auto-detection.Testing
xaito the existingTestProviderRegistry.test_provider_registeredparametrizetest_xai_env_varspinning env vars and default base URLTestProviderRegistryImpact
x-grok-conv-idprompt caching inrun_agent.py"grok"inTOOL_USE_ENFORCEMENT_MODELSinagent/prompt_builder.pyDEFAULT_CONTEXT_LENGTHSfallbacks in fix(model_metadata): add xAI Grok context length fallbacks #7039This PR supersedes the earlier draft #6238 which proposed a narrower and incomplete fix (3 hardcoded context length entries with incorrect values, and a confusing
xai/grok-*entry under the OpenRouter model list).