* feat(x_search): gated X (Twitter) search tool with OAuth-or-API-key auth Salvages tools/x_search_tool.py from the closed PR #10786 (originally by @Jaaneek) and reworks its credential resolution so the tool registers when EITHER xAI credential path is available: * XAI_API_KEY (paid xAI API key) is set in ~/.hermes/.env or the env, OR * The user is signed in via xAI Grok OAuth — SuperGrok subscription — i.e. hermes auth add xai-oauth has been run Both paths route through xAI's built-in x_search Responses tool at https://api.x.ai/v1/responses. When both credentials exist OAuth wins, matching tools/xai_http.py's existing preference order (uses SuperGrok quota instead of paid API spend). The check_fn calls resolve_xai_http_credentials() which auto-refreshes the OAuth access token if it's within the refresh skew window, so a True return means the bearer is fetchable AND non-empty. Wiring - tools/x_search_tool.py — new tool, ~370 LOC. Schema gated by check_fn, bearer resolved per-call so revoked OAuth surfaces a clean tool_error rather than an HTTP 401. - toolsets.py — "x_search" toolset def. NOT added to _HERMES_CORE_TOOLS; users opt in via hermes tools. - hermes_cli/tools_config.py — CONFIGURABLE_TOOLSETS entry + TOOL_CATEGORIES block with two provider options (OAuth + API key) sharing the existing xai_grok post_setup hook for credential bootstrap. - hermes_cli/config.py — DEFAULT_CONFIG["x_search"] with model / timeout_seconds / retries. Additive nested key; no version bump. - tests/tools/test_x_search_tool.py — 13 tests covering HTTP shape, handle validation, citation extraction, 4xx/5xx/timeout handling, and the full credential-resolution matrix (OAuth-only, API-key-only, both-set, neither-set, resolver-raises, config overrides, registry registration). - website/docs/guides/xai-grok-oauth.md — adds X Search to the direct-to-xAI tools section with off-by-default note. - website/docs/user-guide/features/tools.md — new row in the tools table. Off by default — users enable via `hermes tools` → 🐦 X (Twitter) Search. Schema only appears to the model when xAI credentials are configured. Co-authored-by: Jaaneek <Jaaneek@users.noreply.github.com> * docs(x_search): add dedicated feature page + reference entries - website/docs/user-guide/features/x-search.md (new) — full feature walkthrough: authentication, enablement, configuration, parameters, returned fields, example, troubleshooting, see-also links. - website/docs/reference/tools-reference.md — new "x_search" toolset section with parameter docs and credential gating note. - website/docs/reference/toolsets-reference.md — new row in the toolset catalog table. - website/sidebars.ts — wires the new feature page under Media & Web, after web-search. --------- Co-authored-by: Jaaneek <Jaaneek@users.noreply.github.com>
5.5 KiB
| title | description | sidebar_label | sidebar_position |
|---|---|---|---|
| X (Twitter) Search | Search X (Twitter) posts and threads from within the agent using xAI's built-in x_search Responses tool — works with either a SuperGrok OAuth login or an XAI_API_KEY. | X (Twitter) Search | 7 |
X (Twitter) Search
The x_search tool lets the agent search X (Twitter) posts, profiles, and threads directly. It's backed by xAI's built-in x_search tool on the Responses API at https://api.x.ai/v1/responses — Grok itself runs the search server-side and returns synthesized results with citations to the originating posts.
Use this instead of web_search when you specifically want current discussion, reactions, or claims on X. For general web pages, keep using web_search / web_extract.
Authentication
x_search registers when either xAI credential path is available:
| Credential | Source | Setup |
|---|---|---|
| SuperGrok OAuth (preferred) | Browser login at accounts.x.ai, refreshed automatically |
hermes auth add xai-oauth — see xAI Grok OAuth (SuperGrok Subscription) |
XAI_API_KEY |
Paid xAI API key | Set in ~/.hermes/.env |
Both hit the same endpoint with the same payload — the only difference is the bearer token. When both are configured, SuperGrok OAuth wins so x_search runs against your subscription quota instead of paid API spend.
The tool's check_fn runs the xAI credential resolver every time the model's tool list is rebuilt. A True return means the bearer is fetchable AND non-empty AND (if it had expired) successfully refreshed. Revoked tokens with a failed refresh hide the tool from the schema; the model simply can't see it.
Enabling the tool
Off by default. Enable in hermes tools:
hermes tools
# → 🐦 X (Twitter) Search (press space to toggle on)
The picker offers two credential choices:
- xAI Grok OAuth (SuperGrok Subscription) — opens the browser to
accounts.x.aiif you're not already logged in - 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.
Configuration
# ~/.hermes/config.yaml
x_search:
# xAI model used for the Responses call.
# grok-4.20-reasoning is the recommended default; any Grok model
# with x_search tool access works.
model: grok-4.20-reasoning
# Request timeout in seconds. x_search can take 60–120s for
# complex queries — the default is generous. Minimum: 30.
timeout_seconds: 180
# Number of automatic retries on 5xx / ReadTimeout / ConnectionError.
# Each retry backs off (1.5x attempt seconds, capped at 5s).
retries: 2
Tool parameters
The agent calls x_search with these arguments:
| Parameter | Type | Description |
|---|---|---|
query |
string (required) | What to look up on X. |
allowed_x_handles |
string array | Optional list of handles to include exclusively (max 10). Leading @ is stripped. |
excluded_x_handles |
string array | Optional list of handles to exclude (max 10). Mutually exclusive with allowed_x_handles. |
from_date |
string | Optional YYYY-MM-DD start date. |
to_date |
string | Optional YYYY-MM-DD end date. |
enable_image_understanding |
boolean | Ask xAI to analyze images attached to matching posts. |
enable_video_understanding |
boolean | Ask xAI to analyze videos attached to matching posts. |
The tool returns JSON with:
answer— synthesized text response from Grokcitations— citations returned by the Responses API top-level fieldinline_citations—url_citationannotations extracted from the message body (each withurl,title,start_index,end_index)credential_source—"xai-oauth"if OAuth resolved,"xai"if API key resolvedmodel,query,provider,tool,success
Example
Talking to the agent:
What are people on X saying about the new Grok image features? Focus on responses from @xai.
The agent will:
- Call
x_searchwithquery="reactions to new Grok image features",allowed_x_handles=["xai"] - Get back a synthesized answer plus a list of citations linking to specific posts
- Reply with the answer and references
Troubleshooting
"No xAI credentials available"
The tool surfaces this when both auth paths fail. Either set XAI_API_KEY in ~/.hermes/.env or run hermes auth add xai-oauth and complete the browser login. Then restart your session so the agent re-reads the tool registry.
"x_search is not enabled for this model"
The configured x_search.model doesn't have access to the server-side x_search tool. Switch to grok-4.20-reasoning (the default) or another Grok model that supports it. Check the xAI documentation for the current list.
Tool doesn't appear in the schema
Two possible causes:
- Toolset not enabled. Run
hermes toolsand confirm🐦 X (Twitter) Searchis checked. - No xAI credentials. The check_fn returns False, so the schema stays hidden. Run
hermes auth statusto confirm xai-oauth login state, and check thatXAI_API_KEYis set (if you're using the API-key path).
See Also
- xAI Grok OAuth (SuperGrok Subscription) — the OAuth setup guide
- Web Search & Extract — for general (non-X) web search
- Tools Reference — full tool catalog