Semantic search router with mode-based routing, 11 engines, and Reciprocal Rank Fusion.
Current version: 6.1.1 — v6.1 Engine Health Policy is released and the v6 descriptor-backed router is the default path (WRR_V6_ROUTER=1). P1 control-plane hardening (profile matrix, diagnostics, recovery runtime gate, OpenCLI status strict matching, GitHub fast-mode dynamic switching, academic client reuse) is documented in RELEASE_NOTES_v6.1.1.md.
Hermes plugin web_search uses the v6 descriptor-backed registry when
WRR_V6_ROUTER=1, falling back to the v5 mode/RRF route when the variable is unset.
v6.1 completed the S3 default switch: the descriptor-backed registry is the live
default path when WRR_V6_ROUTER=1 (set in the launch environment). The legacy
v5 mode/RRF route remains available by unsetting WRR_V6_ROUTER.
Agent-Reach is the provenance and diagnostic reference for the OpenCLI daemon/extension stack. Runtime community search depends on the opencli binary + daemon + browser extension bridge, not on importing Agent-Reach code.
| Mode | Use case | Engines |
|---|---|---|
| discovery | "what's out there" | exa + brave + github + community |
| grounding | "what's the fact" | exa + brave |
| research | deep investigation | exa (deep) + brave + academic |
| academic | papers only | openalex + semantic-scholar + arxiv |
| platform | platform/community-specific questions | github + community |
| broad | broad practical interest / exploratory queries | exa + brave + community |
| local | search my stuff | supermemory + session + qmd + obsidian |
| recovery | everything failed | searxng |
- Public-web (7): Exa, Brave, GitHub, Community (OpenCLI), Academic (OpenAlex+Semantic Scholar+arXiv), Skill, SearXNG
- Local (4): Supermemory, Session, QMD, Obsidian
Requires Python >= 3.10 (pyproject.toml enforces this). On macOS, /usr/bin/env python3 may resolve to Python 3.9; for direct script usage prefer a 3.10+ environment or call python3.10 ./wrr-cli.py ....
# Install as Hermes plugin
ln -sf ~/code/web-research-router ~/.hermes/plugins/wrr-hermes
# Legacy-compatible CLI examples (run inside Python >=3.10)
./wrr-cli.py doctor # 引擎 + 全量依赖自检
./wrr-cli.py doctor --json # legacy JSON 输出,迁移窗口内 schema 保持不变
./wrr-cli.py search "your query" --provider exa --count 5
./wrr-cli.py fetch "https://example.com" --provider exa --max-chars 2000
./wrr-cli.py similar "https://example.com" --provider exa --count 5
wrr search "your query" # Hermes runtime tool entrypointThree interchangeable entrypoints share one codebase at package version 6.1.1:
# 1) pip install — exposes the `wrr` console script ([project.scripts] wrr = wrr._cli:main).
# Verify the install with the v6 standalone runtime doctor:
pip install .
wrr doctor --v6 --json --runtime standalone
# 2) Direct script — still works without install, on any Python >= 3.10:
./wrr-cli.py doctor --json
./wrr-cli.py search "your query" --provider exa --count 5
# 3) Hermes plugin — plugin.yaml `entry: __init__.py` registers the wrr toolset;
# plugin.yaml `version` is kept aligned with the package version (6.1.1).
ln -sf ~/code/web-research-router ~/.hermes/plugins/wrr-hermesNotes:
- The v6 migration gate stays opt-in: pip/console install does not flip the
default router to v6: legacy
doctor/searchbehavior is unchanged unless you pass--v6(see below). - Wheel verification should confirm the built-in engine manifests are packaged:
pyproject.tomlshipsengines/builtin/*/engine.yamlvia[tool.*] package-data(wrr = ["engines/builtin/*/engine.yaml"]). Afterpython -m build, inspect the wheel (unzip -l dist/*.whl | grep engine.yaml) to ensure every builtin engine manifest is present before publishing.
v6.0 introduced the control-plane CLI; v6.1 completed the S3 default switch and the
Engine Health Policy. Legacy doctor behavior and old JSON consumers still work
when WRR_V6_ROUTER is unset.
# v6 doctor JSON: new shape with runtime/env/discovered/resolved/health/summary/trust
./wrr-cli.py doctor --v6 --json
# Deep health — live probes + bounded recovery for engines that declare it
./wrr-cli.py doctor --v6 --deep --json --runtime standalonev6.1 splits engine health checks into two tiers so the search hot path stays fast and side-effect free:
- Light health (default).
doctor --v6,routable(),autorouting, and everysearchcall read only static / light / cached-live health. They never run a live network probe and never restart a daemon. If a cached live result is absent, the engine is treated by policy, not re-probed on the hot path. - Deep health (
--deep).doctor --v6 --deepopts into live probes. When a manifest declareshealth.recovery, deep doctor may perform a bounded recovery (status → restart once → status). A failed recovery opens the circuit / cooldown; there is no unbounded restart loop. Recovery is not general auto-healing — it happens only under--deep/ an explicitlive_recoverymode.
OpenCLI disconnected remediation. A community OpenCLI engine reporting
rc=0 + Extension: disconnected maps to daemon_disconnected and is not
routable — search will not try to repair it. To recover, connect the Chrome /
OpenCLI extension, then re-run deep doctor to re-probe and (if configured) restart:
# Light health snapshot — no live probes, safe on the hot path
./wrr-cli.py doctor --v6 --json --runtime standalone
# Deep health — live probes + bounded recovery for engines that declare it
./wrr-cli.py doctor --v6 --deep --json --runtime standaloneA future browser-harness fallback may fill community gaps when OpenCLI is unavailable.
Slice 1 (committed) introduces the source adapter seam (wrr/engines/community_sources.py)
and a disabled policy scaffold (wrr/engines/community_policy.py). No real browser
automation is wired into the search hot path; the fallback remains a v6.x candidate.
wrr-cli.py doctor --v6 --profile-matrix --json— per-profile readiness acrosshermes/claude_code/codex/omp; control-plane only;--engine/--tier/--deeprejected.RouterResult.diagnosticscarriesRouteTrace(mode / mode_reason / engines / events / timing) for every search call.config.recovery_allowed(runtime)gates the search recovery fallback. Default allowed:hermes,claude_code,codex,omp. Override withWRR_RECOVERY_ALLOWED_RUNTIMES=hermes,omp,....config.github_fast_mode(env_resolver=...)— runtime-switchable fast-mode decision (no module reload required).- OpenCLI daemon status now requires
daemon: running+extension: connected;not running/disconnectedare explicit failure markers. AcademicEngine.search()reuses onehttpx.AsyncClientacross OpenAlex / Semantic Scholar / arXiv.
See RELEASE_NOTES_v6.1.1.md for the full QA matrix.
Run wrr-cli.py doctor for self-check.
| ID | Source | Required |
|---|---|---|
exa_api_key |
exa.ai | ✅ |
brave_api_key |
brave.com/search/api | ✅ |
github_token |
github.com/settings/tokens | ✅ |
searxng_url |
github.com/searxng/searxng | 可选 |
| ID | Source | Required |
|---|---|---|
last30days_en |
mvanhorn/last30days-skill | ✅ |
last30days_cn |
Jesseovo/last30days-skill-cn | ✅ |
paper_search_mcp |
openags/paper-search-mcp | 可选 |
agent_reach |
Panniantong/Agent-Reach | 参考 |
| ID | Source | Required |
|---|---|---|
opencli |
Panniantong/Agent-Reach | ✅ |
qmd |
github.com/qmd/qmd | ✅ |
| ID | Source | Required |
|---|---|---|
searxng |
github.com/searxng/searxng | 可选 |
| ID | Source |
|---|---|
supermemory |
hermes-agent.nousresearch.com |
session_search |
hermes-agent.nousresearch.com |
# Default environment uses v6 descriptor router.
# Use WRR_V6_ROUTER=0 for legacy registry tests with FakeEngine.
WRR_V6_ROUTER=0 PYTHONPATH=. pytest tests/unit -q| Gate | Command |
|---|---|
| Unit tests | WRR_V6_ROUTER=0 pytest tests/unit -k 'not openalex_live_single_source' -q |
| Installed CLI smoke | wrr doctor --v6 --json --runtime standalone |
| Deep health | wrr doctor --v6 --deep --json --runtime standalone |
MIT