Skip to content

web_search

Web search tool — You.com or Tavily, with a DuckDuckGo fallback.

Engine selection is explicit (engine= or OPENJARVIS_WEB_SEARCH_ENGINE) rather than a chain of try/except layers. The default, "auto", resolves to whichever engine the environment can actually serve, preferring an API-backed engine over the DuckDuckGo HTML scrape:

  • TAVILY_API_KEY set → Tavily (unchanged for existing installs)
  • YOUDOTCOM_API_KEY set → You.com, keyed
  • neither → You.com, keyless free tier (no signup, rate limited per IP)

The keyless tier is what makes a fresh install API-backed with zero config. DuckDuckGo remains the last resort for every engine, and dropping to it is now logged at WARNING with the reason, so a typo'd key no longer looks identical to a working install with quieter results.

Classes

WebSearchTool

WebSearchTool(api_key: str | None = None, max_results: int = 5, *, engine: str | None = None, youcom_api_key: str | None = None)

Bases: BaseTool

Search the web via You.com or Tavily, falling back to DuckDuckGo.

Configure the search engine.

api_key remains the Tavily key, positionally, for backwards compatibility. engine is one of :data:ENGINES; when omitted it comes from OPENJARVIS_WEB_SEARCH_ENGINE and defaults to "auto". An unknown engine name falls back to "auto" with a warning rather than raising, so a typo in the environment cannot break tool loading.

Source code in src/openjarvis/tools/web_search.py
def __init__(
    self,
    api_key: str | None = None,
    max_results: int = 5,
    *,
    engine: str | None = None,
    youcom_api_key: str | None = None,
):
    """Configure the search engine.

    ``api_key`` remains the Tavily key, positionally, for backwards
    compatibility. ``engine`` is one of :data:`ENGINES`; when omitted it
    comes from ``OPENJARVIS_WEB_SEARCH_ENGINE`` and defaults to ``"auto"``.
    An unknown engine name falls back to ``"auto"`` with a warning rather
    than raising, so a typo in the environment cannot break tool loading.
    """
    self._api_key = api_key or os.environ.get("TAVILY_API_KEY")
    self._youcom_api_key = youcom_api_key or os.environ.get(YOUCOM_API_KEY_ENV)
    self._max_results = max_results

    requested = (engine or os.environ.get(ENGINE_ENV) or "auto").strip().lower()
    if requested not in ENGINES:
        logger.warning(
            "Unknown web search engine %r (expected one of %s); using 'auto'",
            requested,
            ", ".join(ENGINES),
        )
        requested = "auto"
    self._engine = requested
Functions

Functions