hermes - 💡(How to fix) Fix [Feature]: Extend credential pool to search backends (Tavily / Exa)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix / Workaround

  • Cross-backend fallback at the dispatcher level (e.g. if Tavily 429s, try Exa). This is a different feature — it masks per-backend bugs, doesn't help users with multiple keys for the same backend, and upstream LLM providers don't do this either. Out of scope here.
  • A shared resolve_search_api_key(provider) helper. Each backend's constraints differ enough (httpx vs SDK, body-only vs Bearer header, cached client vs per-request) that a shared abstraction would either leak details or over-fit one shape. Inlined per-provider resolution mirrors #26031.
RAW_BUFFERClick to expand / collapse

Problem or Use Case

The credential-pool feature in agent/credential_pool.py is provider-agnostic — load_pool(provider: str) accepts any string — and #26031 routes auxiliary LLM providers through it. But the search/web backends in plugins/web/{tavily,exa,brave_free,firecrawl,parallel,...} each load a single API key from os.getenv(...) directly. As a result, users with multiple Tavily or Exa keys:

  • can't round-robin across them
  • can't fail over on 429 / 401 / 403
  • can't register keys via hermes auth add tavily ... (the CLI allowlist rejects the provider name with Unknown provider: tavily)

This blocks the same multi-key resilience that LLM providers already enjoy. I verified by searching open PRs / issues — no in-flight work covers credential pools for search backends; closest prior art is #26031 for auxiliary LLM providers.

Proposed Solution

Pilot the pattern on Tavily and Exa first. They exercise two structurally different integration shapes — raw httpx.post(...) and an SDK with cached client — so the pattern is validated against both before extending to the remaining backends.

For each backend:

  1. Credential resolution — prefer load_pool("<provider>").select() when the pool has entries; fall back to the existing env var. If neither is set, raise the existing ValueError unchanged.
  2. Rotation on 401/403/429 — call pool.mark_exhausted_and_rotate(status_code=...) and retry once with the rotated entry. Other statuses propagate unchanged. (Mirrors the in-pool rotation semantics LLM providers use.)
  3. is_available() — return True when the pool has entries even if the env var is unset.
  4. CLI allowlist — let hermes auth add|list tavily|exa --type api_key ... accept these provider names instead of erroring with Unknown provider.

Once Tavily + Exa land, file follow-up PRs for Brave, Firecrawl, Parallel, Jina, xAI search using the same pattern.

Alternatives Considered

  • Cross-backend fallback at the dispatcher level (e.g. if Tavily 429s, try Exa). This is a different feature — it masks per-backend bugs, doesn't help users with multiple keys for the same backend, and upstream LLM providers don't do this either. Out of scope here.
  • A shared resolve_search_api_key(provider) helper. Each backend's constraints differ enough (httpx vs SDK, body-only vs Bearer header, cached client vs per-request) that a shared abstraction would either leak details or over-fit one shape. Inlined per-provider resolution mirrors #26031.

Feature Type

Configuration option (also: CLI improvement for hermes auth add).

Scope

Medium — touches plugins/web/{tavily,exa}/provider.py, hermes_cli/auth_commands.py, adds two test files (29 cases total), updates docs.

Contribution

  • I'd like to implement this myself and submit a PR (linked below).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Feature]: Extend credential pool to search backends (Tavily / Exa)