refactor(web): dispatch brave-free/ddgs/searxng via web_search_registry

The three migrated providers (brave-free, ddgs, searxng) are now dispatched
through agent.web_search_registry.get_provider() instead of importing
their concrete classes directly. The four inline providers (parallel, exa,
tavily, firecrawl) keep their existing branches — they live in
tools/web_tools.py itself and aren't part of this spike's plugin extraction.

The legacy tools/web_providers/{brave_free,ddgs,searxng}.py modules are
still in place (untouched by this commit) — Task 10 deletes them once the
real migration PR is ready. Keeping them alive during the spike means
revertibility is trivial.

E2E verified:
  1. Plugin discovery registers ['brave-free','ddgs','searxng']
  2. Config web.search_backend: brave-free resolves to the plugin instance
  3. Dispatch result matches the original {success, data.web[]} contract
  4. compile OK; no new LSP errors beyond pre-existing ones in web_tools.py
This commit is contained in:
kshitijk4poor 2026-05-13 23:34:10 +05:30
parent 8f1aa2bf51
commit d8735963f4

View file

@ -1249,29 +1249,26 @@ def web_search_tool(query: str, limit: int = 5) -> str:
_debug.save()
return result_json
if backend == "searxng":
from tools.web_providers.searxng import SearXNGSearchProvider
response_data = SearXNGSearchProvider().search(query, limit)
debug_call_data["results_count"] = len(response_data.get("data", {}).get("web", []))
result_json = json.dumps(response_data, indent=2, ensure_ascii=False)
debug_call_data["final_response_size"] = len(result_json)
_debug.log_call("web_search_tool", debug_call_data)
_debug.save()
return result_json
# Plugin-backed providers (brave-free, ddgs, searxng) — dispatched
# through agent.web_search_registry. Inline providers (parallel,
# exa, tavily, firecrawl) keep their own branches below until they
# too migrate to plugins. Spike scope: only the three providers
# already living in tools/web_providers/ are moved to plugins; the
# rest follow in the real migration PR.
if backend in {"brave-free", "ddgs", "searxng"}:
from agent.web_search_registry import get_provider as _wsp_get_provider
if backend == "brave-free":
from tools.web_providers.brave_free import BraveFreeSearchProvider
response_data = BraveFreeSearchProvider().search(query, limit)
debug_call_data["results_count"] = len(response_data.get("data", {}).get("web", []))
result_json = json.dumps(response_data, indent=2, ensure_ascii=False)
debug_call_data["final_response_size"] = len(result_json)
_debug.log_call("web_search_tool", debug_call_data)
_debug.save()
return result_json
if backend == "ddgs":
from tools.web_providers.ddgs import DDGSSearchProvider
response_data = DDGSSearchProvider().search(query, limit)
provider = _wsp_get_provider(backend)
if provider is None or not provider.supports_search():
response_data = {
"success": False,
"error": (
f"Web search provider '{backend}' is not registered. "
"Run `hermes tools` to set up a provider."
),
}
else:
response_data = provider.search(query, limit)
debug_call_data["results_count"] = len(response_data.get("data", {}).get("web", []))
result_json = json.dumps(response_data, indent=2, ensure_ascii=False)
debug_call_data["final_response_size"] = len(result_json)