mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
feat(x_search): gated X (Twitter) search tool with OAuth-or-API-key auth (#26763)
* 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>
This commit is contained in:
parent
627f8a5f1d
commit
74d0b392e7
11 changed files with 1062 additions and 2 deletions
|
|
@ -128,7 +128,7 @@ hermes --provider x-ai-oauth # alias
|
|||
hermes --provider xai-grok-oauth # alias
|
||||
```
|
||||
|
||||
## Direct-to-xAI Tools (TTS / Image / Video / Transcription)
|
||||
## Direct-to-xAI Tools (TTS / Image / Video / Transcription / X Search)
|
||||
|
||||
Once you're logged in via OAuth, every direct-to-xAI tool reuses the same bearer token automatically — there is **no separate setup** unless you'd rather use an API key.
|
||||
|
||||
|
|
@ -139,6 +139,7 @@ hermes tools
|
|||
# → Text-to-Speech → "xAI TTS"
|
||||
# → Image Generation → "xAI Grok Imagine (image)"
|
||||
# → Video Generation → "xAI Grok Imagine"
|
||||
# → X (Twitter) Search → "xAI Grok OAuth (SuperGrok Subscription)"
|
||||
```
|
||||
|
||||
If OAuth tokens are already stored, the picker confirms it and skips the credential prompt. If neither OAuth nor `XAI_API_KEY` is set, the picker offers a 3-choice menu: OAuth login, paste API key, or skip.
|
||||
|
|
@ -147,6 +148,10 @@ If OAuth tokens are already stored, the picker confirms it and skips the credent
|
|||
The `video_gen` toolset is disabled by default. Enable it in `hermes tools` → `🎬 Video Generation` (press space) before the agent can call `video_generate`. Otherwise the agent may fall back to the bundled ComfyUI skill, which is also tagged for video generation.
|
||||
:::
|
||||
|
||||
:::note X search is off by default
|
||||
The `x_search` toolset is disabled by default. Enable it in `hermes tools` → `🐦 X (Twitter) Search` (press space) before the agent can call `x_search`. The tool routes through xAI's built-in `x_search` Responses API — it works with **either** your SuperGrok OAuth login or a paid `XAI_API_KEY`, and prefers OAuth when both are configured (uses your subscription quota instead of API spend). The tool schema is hidden from the model when no xAI credentials are configured, regardless of whether the toolset is enabled.
|
||||
:::
|
||||
|
||||
### Models
|
||||
|
||||
| Tool | Model | Notes |
|
||||
|
|
|
|||
|
|
@ -196,6 +196,12 @@ Opt-in toolset (not loaded in the default `hermes-cli` set). Add via `--toolsets
|
|||
| `web_search` | Search the web for information. Returns up to 5 results by default with titles, URLs, and descriptions. Accepts an optional `limit` (1-100, default 5). The query is passed through to the configured backend, so operators such as `site:domain`, `filetype:pdf`, `intitle:word`, `-term`, and `"exact phrase"` may work when the backend supports them. | EXA_API_KEY or PARALLEL_API_KEY or FIRECRAWL_API_KEY or TAVILY_API_KEY |
|
||||
| `web_extract` | Extract content from web page URLs. Returns page content in markdown format. Also works with PDF URLs — pass the PDF link directly and it converts to markdown text. Pages under 5000 chars return full markdown; larger pages are LLM-summarized. | EXA_API_KEY or PARALLEL_API_KEY or FIRECRAWL_API_KEY or TAVILY_API_KEY |
|
||||
|
||||
## `x_search` toolset
|
||||
|
||||
| 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 |
|
||||
|
||||
## `tts` toolset
|
||||
|
||||
| Tool | Description | Requires environment |
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ Or in-session:
|
|||
| `vision` | `vision_analyze` | Image analysis via vision-capable models. |
|
||||
| `video` | `video_analyze` | Video analysis and understanding tools (opt-in, not in the default toolset — add explicitly via `--toolsets`). |
|
||||
| `web` | `web_extract`, `web_search` | Web search and page content extraction. |
|
||||
| `x_search` | `x_search` | Search X (Twitter) posts and threads via xAI's built-in `x_search` Responses tool. Off by default; opt in via `hermes tools`. Schema only registered when xAI credentials (SuperGrok OAuth or `XAI_API_KEY`) are configured. |
|
||||
| `yuanbao` | `yb_query_group_info`, `yb_query_group_members`, `yb_search_sticker`, `yb_send_dm`, `yb_send_sticker` | Yuanbao DM/group actions and sticker search. Registered only on `hermes-yuanbao`. |
|
||||
|
||||
## Platform Toolsets
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ High-level categories:
|
|||
| Category | Examples | Description |
|
||||
|----------|----------|-------------|
|
||||
| **Web** | `web_search`, `web_extract` | Search the web and extract page content. |
|
||||
| **X Search** | `x_search` | Search X (Twitter) posts and threads via xAI's built-in `x_search` Responses tool — gated on xAI credentials (SuperGrok OAuth or `XAI_API_KEY`); off by default, opt in via `hermes tools` → 🐦 X (Twitter) Search. |
|
||||
| **Terminal & Files** | `terminal`, `process`, `read_file`, `patch` | Execute commands and manipulate files. |
|
||||
| **Browser** | `browser_navigate`, `browser_snapshot`, `browser_vision` | Interactive browser automation with text and vision support. |
|
||||
| **Media** | `vision_analyze`, `image_generate`, `text_to_speech` | Multimodal analysis and generation. |
|
||||
|
|
|
|||
117
website/docs/user-guide/features/x-search.md
Normal file
117
website/docs/user-guide/features/x-search.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
---
|
||||
title: X (Twitter) Search
|
||||
description: 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.
|
||||
sidebar_label: X (Twitter) Search
|
||||
sidebar_position: 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)](../../guides/xai-grok-oauth.md) |
|
||||
| **`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`:
|
||||
|
||||
```bash
|
||||
hermes tools
|
||||
# → 🐦 X (Twitter) Search (press space to toggle on)
|
||||
```
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# ~/.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 Grok
|
||||
- `citations` — citations returned by the Responses API top-level field
|
||||
- `inline_citations` — `url_citation` annotations extracted from the message body (each with `url`, `title`, `start_index`, `end_index`)
|
||||
- `credential_source` — `"xai-oauth"` if OAuth resolved, `"xai"` if API key resolved
|
||||
- `model`, `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:
|
||||
|
||||
1. Call `x_search` with `query="reactions to new Grok image features"`, `allowed_x_handles=["xai"]`
|
||||
2. Get back a synthesized answer plus a list of citations linking to specific posts
|
||||
3. 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](https://docs.x.ai/) for the current list.
|
||||
|
||||
### Tool doesn't appear in the schema
|
||||
|
||||
Two possible causes:
|
||||
|
||||
1. **Toolset not enabled.** Run `hermes tools` and confirm `🐦 X (Twitter) Search` is checked.
|
||||
2. **No xAI credentials.** The check_fn returns False, so the schema stays hidden. Run `hermes auth status` to confirm xai-oauth login state, and check that `XAI_API_KEY` is set (if you're using the API-key path).
|
||||
|
||||
## See Also
|
||||
|
||||
- [xAI Grok OAuth (SuperGrok Subscription)](../../guides/xai-grok-oauth.md) — the OAuth setup guide
|
||||
- [Web Search & Extract](web-search.md) — for general (non-X) web search
|
||||
- [Tools Reference](../../reference/tools-reference.md) — full tool catalog
|
||||
|
|
@ -83,6 +83,7 @@ const sidebars: SidebarsConfig = {
|
|||
items: [
|
||||
'user-guide/features/voice-mode',
|
||||
'user-guide/features/web-search',
|
||||
'user-guide/features/x-search',
|
||||
'user-guide/features/browser',
|
||||
'user-guide/features/computer-use',
|
||||
'user-guide/features/vision',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue