Skip to content

feat(providers): add native xAI provider#7050

Closed
Julientalbot wants to merge 1 commit into
NousResearch:mainfrom
Julientalbot:feat/native-xai-provider
Closed

feat(providers): add native xAI provider#7050
Julientalbot wants to merge 1 commit into
NousResearch:mainfrom
Julientalbot:feat/native-xai-provider

Conversation

@Julientalbot

@Julientalbot Julientalbot commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Problem

xAI is listed in models.dev (id: xai, env: [XAI_API_KEY]) but without an api field. As a result, get_provider('xai') in hermes_cli/providers.py returns a ProviderDef with an empty base_url, and xAI is absent from PROVIDER_REGISTRY in hermes_cli/auth.py and from _PROVIDER_MODELS in hermes_cli/models.py.

Users pointing at xAI direct have to work around this with a custom provider:

model:
  default: grok-4.20-0309-reasoning
  provider: custom
  base_url: https://api.x.ai/v1

This loses the ergonomics of a first-class provider:

  • No hermes model --provider xai catalog listing
  • No auto-detection from XAI_API_KEY (has to rely on OPENAI_API_KEY fallback inside provider: custom)
  • No label in status/banner output
  • No alias resolution for x-ai / x.ai
  • No URL-based provider inference (so _infer_provider_from_url can'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, alibaba and friends.

hermes_cli/auth.py

Register PROVIDER_REGISTRY['xai']:

"xai": ProviderConfig(
    id="xai",
    name="xAI",
    auth_type="api_key",
    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 (since models.dev doesn't provide one), register x-ai / 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 so hermes model --provider xai and curated_models_for_provider('xai') return a usable catalog:

grok-4.20-0309-reasoning
grok-4.20-0309-non-reasoning
grok-4.20-multi-agent-0309
grok-4-1-fast-reasoning
grok-4-1-fast-non-reasoning
grok-4-fast-reasoning
grok-4-fast-non-reasoning
grok-4-0709
grok-code-fast-1
grok-3
grok-3-mini

(grok-2-* and grok-*-vision excluded from the curated list — older / image-only.)

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).

Usage after this change

model:
  default: grok-4.20-0309-reasoning
  provider: xai

No base_url needed. XAI_API_KEY is auto-detected. The provider integrates with the existing credential pool, banner, hermes model listing, and status output like any other native provider.

The legacy provider: custom + base_url: https://api.x.ai/v1 configuration also keeps working, and now benefits from correct context-length auto-detection.

Testing

  • Added xai to the existing TestProviderRegistry.test_provider_registered parametrize
  • Added dedicated test_xai_env_vars pinning env vars and default base URL
  • 21/21 tests pass on TestProviderRegistry
$ pytest tests/hermes_cli/test_api_key_providers.py::TestProviderRegistry
21 passed in 0.61s

Impact

  • Zero regression for other providers
  • Users on xAI direct get a first-class provider experience
  • Legacy custom-endpoint configurations get automatic context-length resolution via URL inference
  • Complements the existing xAI integration:

This 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).

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.
@Julientalbot Julientalbot force-pushed the feat/native-xai-provider branch from 9cc477e to 703e676 Compare April 10, 2026 08:54
Julientalbot pushed a commit to Julientalbot/hermes-agent that referenced this pull request Apr 10, 2026
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.
@Julientalbot

Copy link
Copy Markdown
Contributor Author

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 api.x.aixai entry in _URL_TO_PROVIDER (agent/model_metadata.py). That single line is orthogonal — it lets the legacy provider: custom + base_url: https://api.x.ai/v1 configuration benefit from the context length fallbacks merged in #7093 without needing the full native provider. Let me know which shape works best.

teknium1 pushed a commit that referenced this pull request Apr 10, 2026
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
@teknium1 teknium1 closed this in 8bcb8b8 Apr 10, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #7372. Your xAI provider implementation was cherry-picked with authorship preserved — clean, well-structured, follows existing patterns perfectly. Thanks, @Julientalbot!

@Julientalbot

Copy link
Copy Markdown
Contributor Author

@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!

Tommyeds pushed a commit to Tommyeds/hermes-agent that referenced this pull request Apr 12, 2026
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
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 28, 2026
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
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
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
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
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
olympus-terminal pushed a commit to olympus-terminal/hermes-agent that referenced this pull request May 16, 2026
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
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
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
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants