Files
nanobot/docs/web-search.md
Chris Alexander 71d90de31b feat(web): configurable web search providers with fallback
Add multi-provider web search support: Brave (default), Tavily,
DuckDuckGo, and SearXNG. Falls back to DuckDuckGo when provider
credentials are missing. Providers are dispatched via a map with
register_provider() for plugin extensibility.

- WebSearchConfig with env-var resolution and from_legacy() bridge
- Config migration for legacy flat keys (tavilyApiKey, searxngBaseUrl)
- SearXNG URL validation, explicit error for unknown providers
- ddgs package (replaces deprecated duckduckgo-search)
- 16 tests covering all providers, fallback, env resolution, edge cases
- docs/web-search.md with full config reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:36:14 +00:00

1.9 KiB

Web Search Providers

NanoBot supports multiple web search providers. Configure in ~/.nanobot/config.json under tools.web.search.

Provider Key Env var
brave (default) apiKey BRAVE_API_KEY
tavily apiKey TAVILY_API_KEY
searxng baseUrl SEARXNG_BASE_URL
duckduckgo

Each provider uses the same apiKey field — set the provider and key together. If no provider is specified but apiKey is given, Brave is assumed.

When credentials are missing and fallbackToDuckduckgo is true (the default), searches fall back to DuckDuckGo automatically.

Examples

Brave (default — just set the key):

{
  "tools": {
    "web": {
      "search": {
        "apiKey": "BSA..."
      }
    }
  }
}

Tavily:

{
  "tools": {
    "web": {
      "search": {
        "provider": "tavily",
        "apiKey": "tvly-..."
      }
    }
  }
}

SearXNG (self-hosted, no API key needed):

{
  "tools": {
    "web": {
      "search": {
        "provider": "searxng",
        "baseUrl": "https://searx.example"
      }
    }
  }
}

DuckDuckGo (no credentials required):

{
  "tools": {
    "web": {
      "search": {
        "provider": "duckduckgo"
      }
    }
  }
}

Options

Key Type Default Description
provider string "brave" Search backend
apiKey string "" API key for the selected provider
baseUrl string "" Base URL for SearXNG (appends /search)
maxResults integer 5 Default results per search
fallbackToDuckduckgo boolean true Fall back to DuckDuckGo when credentials are missing

Custom providers

Plugins can register additional providers at runtime via the dispatch dict:

async def my_search(query: str, n: int) -> str:
    ...

tool._provider_dispatch["my-engine"] = my_search