hermes-agent/hermes_cli
Teknium 4433b83378
feat(web): add Parallel as alternative web search/extract backend (#1696)
* feat(web): add Parallel as alternative web search/extract backend

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>

* fix: add PARALLEL_API_KEY to config registry and fix web_crawl policy 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)

* refactor: explicit backend selection via hermes tools, not auto-detect

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

* refactor: use config.yaml for web backend, not env var

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

---------

Co-authored-by: s-jag <s-jag@users.noreply.github.com>
2026-03-17 04:02:02 -07:00
..
__init__.py chore: release v0.3.0 (v2026.3.17) 2026-03-17 00:38:48 -07:00
auth.py fix: remove ANTHROPIC_BASE_URL env var to avoid collisions (#1675) 2026-03-17 02:51:49 -07:00
banner.py fix(cli): non-blocking startup update check and banner deduplication 2026-03-14 21:45:50 -07:00
callbacks.py refactor(cli): implement approval locking mechanism to serialize concurrent requests 2026-03-13 23:59:18 -07:00
checklist.py fix: skip hanging tests + add global test timeout 2026-03-12 01:23:28 -07:00
claw.py fix(claw): warn when API keys are skipped during OpenClaw migration (#1580) 2026-03-17 02:10:36 -07:00
clipboard.py fix: clean up empty file after failed wl-paste clipboard extraction 2026-03-11 02:56:19 -07:00
codex_models.py fix: add codex forward-compat model listing 2026-03-13 21:34:01 -07:00
colors.py feat(cli): skin-aware light/dark theme mode with terminal auto-detection 2026-03-17 02:51:40 -07:00
commands.py feat: add /tools disable/enable/list slash commands with session reset (#1652) 2026-03-17 02:05:26 -07:00
config.py feat(web): add Parallel as alternative web search/extract backend (#1696) 2026-03-17 04:02:02 -07:00
cron.py docs: clarify gateway service scopes (#1378) 2026-03-14 21:17:41 -07:00
curses_ui.py refactor: extract shared curses checklist, fix skill discovery perf 2026-03-11 03:06:15 -07:00
default_soul.py feat: seed a default global SOUL.md 2026-03-14 08:05:30 -07:00
doctor.py feat: add Kilo Code (kilocode) as first-class inference provider (#1666) 2026-03-17 02:40:34 -07:00
env_loader.py fix(config): reload .env over stale shell overrides 2026-03-15 06:46:28 -07:00
gateway.py feat(gateway): wire DingTalk into gateway setup and platform maps (#1690) 2026-03-17 03:19:45 -07:00
main.py docs: add Alibaba Cloud and DingTalk to setup wizard and docs (#1687) 2026-03-17 03:13:58 -07:00
models.py fix(cli): use keyword args for fetch_nous_models (always TypeError) 2026-03-17 03:42:46 -07:00
pairing.py Cleanup time! 2026-02-20 23:23:32 -08:00
plugins.py feat: first-class plugin architecture (#1555) 2026-03-16 07:17:36 -07:00
runtime_provider.py fix: remove ANTHROPIC_BASE_URL env var to avoid collisions (#1675) 2026-03-17 02:51:49 -07:00
setup.py feat(web): add Parallel as alternative web search/extract backend (#1696) 2026-03-17 04:02:02 -07:00
skills_config.py fix: wire email platform into toolset mappings + add documentation 2026-03-11 06:34:32 -07:00
skills_hub.py fix: add --yes flag to bypass confirmation in /skills install and uninstall (#1647) 2026-03-17 01:59:07 -07:00
skin_engine.py feat(cli): skin-aware light/dark theme mode with terminal auto-detection 2026-03-17 02:51:40 -07:00
status.py feat: add SMS (Twilio) platform adapter 2026-03-17 03:14:53 -07:00
tools_config.py feat(web): add Parallel as alternative web search/extract backend (#1696) 2026-03-17 04:02:02 -07:00
uninstall.py feat(gateway): scope systemd service name to HERMES_HOME 2026-03-16 04:42:46 -07:00