Skip to content

feat(web): add Parallel as alternative web search/extract backend#1696

Merged
teknium1 merged 4 commits intomainfrom
hermes/hermes-3fc35e7b
Mar 17, 2026
Merged

feat(web): add Parallel as alternative web search/extract backend#1696
teknium1 merged 4 commits intomainfrom
hermes/hermes-3fc35e7b

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

@teknium1 teknium1 commented Mar 17, 2026

Summary

Salvage of PR #1578 by @s-jag (cherry-picked onto current main with authorship preserved).

Adds Parallel as a drop-in alternative to Firecrawl for web_search and web_extract tools, using the official parallel-web Python SDK.

What changed

  • Explicit backend selection via hermes tools — user picks Firecrawl or Parallel during setup, choice saved as WEB_SEARCH_BACKEND in .env. No auto-detect guessing.
  • Fully backward compatible — existing Firecrawl users keep working. If WEB_SEARCH_BACKEND isn't set, falls back to whichever key is present.
  • web_crawl_tool remains Firecrawl-only (Parallel has no crawl API) with a clear error if Firecrawl is unavailable.
  • Lazy SDK importsfrom parallel import Parallel inside client getters, no import-time side effects.
  • parallel-web>=0.4.2 added — zero new transitive deps (uses httpx + pydantic already in tree).

Commits

  1. Cherry-pick (author: @s-jag) — Parallel SDK integration, backend dispatch, 16 new tests
  2. Follow-upPARALLEL_API_KEY in config registry, fix web_crawl policy tests for Firecrawl guard
  3. Refactor — Replace auto-detect with explicit hermes tools selection. _configure_provider() saves WEB_SEARCH_BACKEND to .env, _is_provider_active() shows [active] marker.

Files changed

File Change
tools/web_tools.py Backend dispatch, Parallel SDK clients, explicit _get_backend()
hermes_cli/tools_config.py web_backend key on providers, saves WEB_SEARCH_BACKEND on selection
hermes_cli/config.py PARALLEL_API_KEY in OPTIONAL_ENV_VARS, set_config_value, doctor keys
hermes_cli/setup.py Status check accepts either backend
tools/environments/local.py Env blocklist additions
pyproject.toml / requirements.txt parallel-web>=0.4.2
tests/tools/test_web_tools_config.py 16 new tests, updated docstrings for explicit selection
tests/tools/test_website_policy.py Fix web_crawl tests for Firecrawl guard
.env.example, docs Documentation updates

Test plan

  • pytest tests/tools/test_web_tools_config.py — 24/24 pass
  • pytest tests/tools/test_website_policy.py — 22/22 pass
  • Full suite — 5089 passed, 16 failed (all pre-existing, none related)

Closes #1578


Disclosure: The original contributor (@s-jag) disclosed they are associated with Parallel Web Systems.

s-jag and others added 4 commits March 17, 2026 03:32
Adds Parallel (parallel.ai) as a drop-in alternative to Firecrawl for
web_search and web_extract tools using the official parallel-web SDK.

- Backend selection via WEB_SEARCH_BACKEND env var (auto/parallel/firecrawl)
- Auto mode prefers Firecrawl when both keys present; Parallel when sole backend
- web_crawl remains Firecrawl-only with clear error when unavailable
- Lazy SDK imports, interrupt support, singleton clients
- 16 new unit tests for backend selection and client config

Co-authored-by: s-jag <s-jag@users.noreply.github.com>
… tests

Follow-up for Parallel backend integration:
- Add PARALLEL_API_KEY to OPTIONAL_ENV_VARS (hermes doctor, env blocklist)
- Add to set_config_value api_keys list (hermes config set)
- Add to doctor keys display
- Fix 2 web_crawl policy tests that didn't set FIRECRAWL_API_KEY
  (needed now that web_crawl has a Firecrawl availability guard)
Replace the auto-detect backend selection with explicit user choice:
- hermes tools saves WEB_SEARCH_BACKEND to .env when user picks a provider
- _get_backend() reads the explicit choice first
- Fallback only for manual/legacy config (uses whichever key is present)
- _is_provider_active() shows [active] for the selected web backend
- Updated tests, docs, and .env.example to remove 'auto' mode language
Match the TTS/browser pattern — web.backend is stored in config.yaml
(set by hermes tools), not as a WEB_SEARCH_BACKEND env var.

- _load_web_config() reads web: section from config.yaml
- _get_backend() reads web.backend from config, falls back to key detection
- _configure_provider() saves to config dict (saved to config.yaml)
- _is_provider_active() reads from config dict
- Removed WEB_SEARCH_BACKEND from .env.example, set_config_value, docs
- Updated all tests to mock _load_web_config instead of env vars
@teknium1 teknium1 merged commit 4433b83 into main Mar 17, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants