feat(web): add xAI Web Search provider plugin#29042
Merged
Merged
Conversation
Adds a new bundled web search provider plugin backed by xAI's agentic Web Search tool (server-side `web_search` on the Responses API). Slots in alongside the existing Firecrawl / Tavily / Exa / Brave / SearXNG / DDGS providers; opt in via `web.backend: xai` (or auto-selected by the registry's single-provider shortcut when it's the only available web provider, matching every other backend's behavior). Reuses the existing xAI HTTP credential plumbing (`tools/xai_http.py`) so it works with both `hermes auth login xai-oauth` (SuperGrok OAuth) and `XAI_API_KEY` — no new credential paths, no new env vars, no new setup-wizard prompts. The existing `xai_grok` post_setup hook handles credential collection. Reference: https://docs.x.ai/developers/tools/web-search Provider behavior ----------------- - Sends a structured prompt to Grok with `tools=[{"type": "web_search"}]` enabled and `include=["no_inline_citations"]`, then parses results from a `{"results": [...]}` JSON block (primary), falling back to `url_citation` annotations (secondary) and the top-level `citations` list (last-ditch). Annotation fallback falls through to citations when no rows are extractable, so future annotation types xAI may add don't silently mask real data. - HTTP 200 + `{"error": {...}}` envelopes (model-overload, refusal) are surfaced as failures rather than masked as success-with-empty- results. - HTTP 401 on the OAuth path triggers a single `force_refresh=True` retry — closes two gaps the resolver's proactive JWT-exp shortcut doesn't cover: opaque (non-JWT) access tokens and mid-window revocation. Env-var (`XAI_API_KEY`) credentials never retry; they can't be refreshed and an immediate retry would just burn quota. - `is_available()` is a cheap probe (env var OR auth.json read), never invokes the OAuth resolver — required by the ABC contract because it runs on every `hermes tools` repaint and at tool-registration time. - Class docstring documents the LLM-in-a-trench-coat trust model so callers piping untrusted input into `web_search` know returned URLs are model-generated and should be validated before fetching. Config (`config.yaml`): web: backend: xai xai: model: grok-4.3 # optional, defaults to grok-4.3 allowed_domains: # optional, max 5 — mutex with excluded_domains - arxiv.org excluded_domains: # optional, max 5 - example-spam.com timeout: 90 # optional, seconds Files ----- - plugins/web/xai/plugin.yaml (new) plugin manifest - plugins/web/xai/__init__.py (new) register(ctx) hook - plugins/web/xai/provider.py (new) XAIWebSearchProvider impl - tools/xai_http.py (+47) has_xai_credentials() cheap-probe helper + keyword-only force_refresh arg on resolve_xai_http_ credentials() (backwards compatible; all 9 other call sites unaffected) - tools/web_tools.py (+11) "xai" added to configured- backend set + branch in _is_backend_available() - tests/tools/test_web_providers_xai.py (new, 39 tests) covers identity, cheap-probe semantics, JSON / annotation / citations parse paths, request payload shape, error envelopes, OAuth force-refresh-on-401 retry, env-var-no-retry guard, 500-not- retried guard, refresh-returns- same-token guard, OAuth runtime resolution, and backend wiring. Tests ----- - 39 xai-suite passes - 79 sibling web-provider tests (brave-free, ddgs, searxng, base) pass - 119 cross-suite tests for other xai_http callers (transcription, x_search, tts) pass — verifies the new keyword-only arg is BC - scripts/check-windows-footguns.py: clean on all 5 modified files No edits to run_agent.py, cli.py, gateway/, toolsets, config schema, plugin core, or auth core.
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-attribute |
2 |
unresolved-import |
2 |
invalid-argument-type |
1 |
unsupported-operator |
1 |
First entries
tests/tools/test_web_providers_xai.py:514: [unresolved-attribute] unresolved-attribute: Attribute `append` is not defined on `int` in union `list[Unknown] | int`
tests/tools/test_web_providers_xai.py:515: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `list[Unknown] | int`
tests/tools/test_web_providers_xai.py:521: [unsupported-operator] unsupported-operator: Operator `+=` is not supported between objects of type `list[Unknown]` and `Literal[1]`
plugins/web/xai/provider.py:189: [unresolved-attribute] unresolved-attribute: Attribute `strip` is not defined on `None` in union `Any | None | Literal["grok-4.3"]`
tests/tools/test_web_providers_xai.py:614: [unresolved-import] unresolved-import: Cannot resolve imported module `httpx`
plugins/web/xai/provider.py:233: [unresolved-import] unresolved-import: Cannot resolve imported module `httpx`
✅ Fixed issues: none
Unchanged: 4725 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
teknium1
added a commit
that referenced
this pull request
May 20, 2026
Follow-up to #29042 (xAI Web Search provider plugin). Adds xAI to the canonical user-facing and developer-facing docs, with the search-only caveat and the LLM-in-a-trench-coat trust model carried over from the class docstring. - user-guide/features/web-search.md - Backends table: new xAI row + extended search-only note - New 'xAI (Grok)' setup section with config knobs and trust-model caution admonition - Single-backend yaml comment now lists 'xai' - Auto-detection table: explicitly note that xAI is NOT auto-detected (XAI_API_KEY is shared with inference/TTS/image-gen so we don't silently take over web for users who only set it for chat) - developer-guide/web-search-provider-plugin.md - Added plugins/web/xai/ to the 'study these next' reference list - reference/environment-variables.md - XAI_API_KEY description now also mentions web search
Lillard01
pushed a commit
to Lillard01/hermes-agent
that referenced
this pull request
May 21, 2026
Follow-up to NousResearch#29042 (xAI Web Search provider plugin). Adds xAI to the canonical user-facing and developer-facing docs, with the search-only caveat and the LLM-in-a-trench-coat trust model carried over from the class docstring. - user-guide/features/web-search.md - Backends table: new xAI row + extended search-only note - New 'xAI (Grok)' setup section with config knobs and trust-model caution admonition - Single-backend yaml comment now lists 'xai' - Auto-detection table: explicitly note that xAI is NOT auto-detected (XAI_API_KEY is shared with inference/TTS/image-gen so we don't silently take over web for users who only set it for chat) - developer-guide/web-search-provider-plugin.md - Added plugins/web/xai/ to the 'study these next' reference list - reference/environment-variables.md - XAI_API_KEY description now also mentions web search
Gpapas
pushed a commit
to Gpapas/hermes-agent
that referenced
this pull request
May 23, 2026
Follow-up to NousResearch#29042 (xAI Web Search provider plugin). Adds xAI to the canonical user-facing and developer-facing docs, with the search-only caveat and the LLM-in-a-trench-coat trust model carried over from the class docstring. - user-guide/features/web-search.md - Backends table: new xAI row + extended search-only note - New 'xAI (Grok)' setup section with config knobs and trust-model caution admonition - Single-backend yaml comment now lists 'xai' - Auto-detection table: explicitly note that xAI is NOT auto-detected (XAI_API_KEY is shared with inference/TTS/image-gen so we don't silently take over web for users who only set it for chat) - developer-guide/web-search-provider-plugin.md - Added plugins/web/xai/ to the 'study these next' reference list - reference/environment-variables.md - XAI_API_KEY description now also mentions web search
Mucky010
pushed a commit
to Mucky010/hermes-agent
that referenced
this pull request
May 24, 2026
Follow-up to NousResearch#29042 (xAI Web Search provider plugin). Adds xAI to the canonical user-facing and developer-facing docs, with the search-only caveat and the LLM-in-a-trench-coat trust model carried over from the class docstring. - user-guide/features/web-search.md - Backends table: new xAI row + extended search-only note - New 'xAI (Grok)' setup section with config knobs and trust-model caution admonition - Single-backend yaml comment now lists 'xai' - Auto-detection table: explicitly note that xAI is NOT auto-detected (XAI_API_KEY is shared with inference/TTS/image-gen so we don't silently take over web for users who only set it for chat) - developer-guide/web-search-provider-plugin.md - Added plugins/web/xai/ to the 'study these next' reference list - reference/environment-variables.md - XAI_API_KEY description now also mentions web search
1 task
Bryce-huang
pushed a commit
to wbkunlun/hermes-agent
that referenced
this pull request
May 29, 2026
Follow-up to NousResearch#29042 (xAI Web Search provider plugin). Adds xAI to the canonical user-facing and developer-facing docs, with the search-only caveat and the LLM-in-a-trench-coat trust model carried over from the class docstring. - user-guide/features/web-search.md - Backends table: new xAI row + extended search-only note - New 'xAI (Grok)' setup section with config knobs and trust-model caution admonition - Single-backend yaml comment now lists 'xai' - Auto-detection table: explicitly note that xAI is NOT auto-detected (XAI_API_KEY is shared with inference/TTS/image-gen so we don't silently take over web for users who only set it for chat) - developer-guide/web-search-provider-plugin.md - Added plugins/web/xai/ to the 'study these next' reference list - reference/environment-variables.md - XAI_API_KEY description now also mentions web search #AI commit#
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
Follow-up to NousResearch#29042 (xAI Web Search provider plugin). Adds xAI to the canonical user-facing and developer-facing docs, with the search-only caveat and the LLM-in-a-trench-coat trust model carried over from the class docstring. - user-guide/features/web-search.md - Backends table: new xAI row + extended search-only note - New 'xAI (Grok)' setup section with config knobs and trust-model caution admonition - Single-backend yaml comment now lists 'xai' - Auto-detection table: explicitly note that xAI is NOT auto-detected (XAI_API_KEY is shared with inference/TTS/image-gen so we don't silently take over web for users who only set it for chat) - developer-guide/web-search-provider-plugin.md - Added plugins/web/xai/ to the 'study these next' reference list - reference/environment-variables.md - XAI_API_KEY description now also mentions web search
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Salvage of #29036 by @Jaaneek onto current main.
Summary
New bundled web-search provider under
plugins/web/xai/— slots alongside Brave/Tavily/Exa/Firecrawl/SearXNG/DDGS. Opt in viaweb.backend: xai. Reuses existing xAI Grok OAuth /XAI_API_KEYcredential plumbing; no new credential paths, no new env vars, no setup-wizard prompts.Changes
plugins/web/xai/{plugin.yaml,__init__.py,provider.py}— new plugin, 560-line providertools/xai_http.py— adds cheaphas_xai_credentials()probe + keyword-onlyforce_refresharg onresolve_xai_http_credentials()(fully BC)tools/web_tools.py— 11 lines: "xai" added to configured-backend set +_is_backend_availablebranchtests/tools/test_web_providers_xai.py— 39 testsDesign notes
is_available()is a cheap probe (env var OR auth.json read); never invokes the OAuth resolver — honors the ABC contract that it's called on everyhermes toolsrepaintforce_refresh=Trueretry; env-var creds skip the retry (can't refresh){error: ...}envelopes surface as failures, not empty-resultsValidation
test_web_providers_xai.py)xai_httpcallers (tts/x_search/video_gen)Authorship preserved via cherry-pick. Closes #29036.