Skip to content

feat(tools): add SearXNG web search provider#214

Merged
qhkm merged 7 commits intomainfrom
feat/searxng-search-provider
Mar 3, 2026
Merged

feat(tools): add SearXNG web search provider#214
qhkm merged 7 commits intomainfrom
feat/searxng-search-provider

Conversation

@qhkm
Copy link
Copy Markdown
Owner

@qhkm qhkm commented Mar 2, 2026

Summary

  • Add SearXNG as a third web search provider alongside Brave and DuckDuckGo
  • Add explicit provider field to WebSearchConfig for user choice ("brave", "searxng", "ddg")
  • Add api_url field for self-hosted SearXNG instance URL
  • Auto-detection fallback: api_url set → SearXNG, api_key set → Brave, else → DuckDuckGo
  • Env overrides: ZEPTOCLAW_TOOLS_WEB_SEARCH_PROVIDER, ZEPTOCLAW_TOOLS_WEB_SEARCH_API_URL

Closes #196

Test plan

  • 11 unit tests for SearxngSearchTool (JSON parsing, URL validation, tool properties)
  • 2 config tests (defaults, deserialization)
  • 1 env override test
  • Full test suite passes (2772 lib tests)
  • cargo clippy -- -D warnings clean
  • Manual test with self-hosted SearXNG instance

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added SearXNG as a new web search provider option
    • Implemented automatic provider detection based on available configuration
  • Configuration

    • New environment variable ZEPTOCLAW_TOOLS_WEB_SEARCH_PROVIDER to select search provider (brave, searxng, ddg)
    • New environment variable ZEPTOCLAW_TOOLS_WEB_SEARCH_API_URL to specify custom search API endpoint

qhkm and others added 6 commits March 2, 2026 15:31
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add SearxngSearchTool to the public re-exports in src/tools/mod.rs and
src/lib.rs so downstream users and the CLI wiring layer can import it.
Also extend the module doc comment to document the new tool.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the 2-way Brave/DDG branch in create_agent_with_template() with
a 3-way resolver that checks an explicit `provider` config field first,
then auto-detects: api_url present → SearXNG, api_key present → Brave,
fallback → DuckDuckGo. Both SearXNG and Brave paths emit a clear error
if the required URL/key is missing when that provider is selected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6ef217 and 5a8f860.

📒 Files selected for processing (2)
  • src/cli/common.rs
  • src/tools/web.rs

📝 Walkthrough

Walkthrough

Adds SearXNG as an additional web search provider: new SearxngSearchTool (validation, JSON parsing, execution), config fields and env overrides for provider/api_url, wiring in CLI/tool registration, and public re-exports; includes related tests and docs updates. (≤50 words)

Changes

Cohort / File(s) Summary
Config — types & env
src/config/types.rs, src/config/mod.rs
Add provider: Option<String> and api_url: Option<String> to WebSearchConfig; implement env overrides ZEPTOCLAW_TOOLS_WEB_SEARCH_PROVIDER and ZEPTOCLAW_TOOLS_WEB_SEARCH_API_URL and unit test for provider override.
SearXNG web tool
src/tools/web.rs
Add SearxngSearchTool (constructors, with_max_results), URL validation (validate_searxng_url), JSON parsing (parse_searxng_json), Tool trait implementation, execution logic and tests for SearXNG flows.
CLI wiring & provider selection
src/cli/common.rs
Add provider selection/auto-detection logic; validate provider-specific requirements; register SearxngSearchTool when configured; integrate provider messages and error handling.
Re-exports / catalog
src/tools/mod.rs, src/lib.rs
Re-export SearxngSearchTool and update built-in tools documentation and public export lists.
Docs
CLAUDE.md
Document SearXNG as an additional web search provider and list new environment variables for provider/API URL configuration.
Other additions (high-level)
src/tools/..., src/tools/mcp/...
Large set of new tool modules and MCP client submodules added (docx_read, transcribe, http_request, project, screenshot, custom, hardware, google, gsheets, message, memory, longterm_memory, cron, spawn, delegate, composed, plugin, skills_install, skills_search, approval, r8r, reminder; plus protocol.rs, transport.rs, client.rs, wrapper.rs). These are added alongside SearXNG but require separate review.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI/Request
  participant Config as Config
  participant ToolReg as ToolRegistry
  participant Searx as SearXNG API
  CLI->>Config: read provider/api_url (env overrides)
  Config-->>CLI: provider selection
  CLI->>ToolReg: request web search tool
  ToolReg-->>CLI: instantiate SearxngSearchTool(api_url)
  CLI->>Searx: HTTP query (search term)
  Searx-->>CLI: JSON results
  CLI->>ToolReg: parse_searxng_json -> SearchResult[]
  CLI-->>ToolReg: return formatted output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 In burrows of code I hop and cheer,

SearXNG's new trail now bright and clear.
Self-hosted search with open sky,
I sniff the indexes, give it a try —
Hoppity-hop, new tools draw near!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 74.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main feature addition: SearXNG web search provider.
Linked Issues check ✅ Passed The PR fully implements the objective from #196: adds SearXNG as a web search provider with configuration support for self-hosted instances.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing SearXNG support: configuration, web search tool implementation, provider selection logic, and tests—no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/searxng-search-provider

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/cli/common.rs`:
- Around line 755-817: The code currently treats any explicit provider string
(search_cfg.provider) as valid and silently falls back to DdgSearchTool when it
doesn't match known providers; change the provider-determination so that if
search_cfg.provider is Some(non-empty) you validate it (normalize case/trim) and
if it is not one of the known values ("searxng", "brave", "ddg") return an error
(e.g. Err(anyhow::anyhow!("Unknown search provider: {}", provider))) instead of
defaulting, otherwise keep the existing inference behavior (check
api_url/api_key) when provider is not specified; update the branch that uses
provider to rely on the validated string and keep
SearxngSearchTool::with_max_results, WebSearchTool::with_max_results and
DdgSearchTool::with_max_results usage unchanged.

In `@src/tools/web.rs`:
- Around line 458-470: Change the SearXNG constructors to return Result<Self,
Error> instead of calling expect(): replace pub fn new(api_url: &str) -> Self
and pub fn with_max_results(api_url: &str, max_results: usize) -> Self so they
call validate_searxng_url(api_url) and propagate the failure (e.g., ? or
map_err) returning an Err on invalid URL; update SearxngSearchTool construction
sites (notably the call in src/cli/common.rs that uses
.register_tool(Box::new(SearxngSearchTool::with_max_results(url, max)?))) to
handle the Result (propagate or map error) so startup no longer panics on bad
config.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01648b9 and c6ef217.

📒 Files selected for processing (7)
  • CLAUDE.md
  • src/cli/common.rs
  • src/config/mod.rs
  • src/config/types.rs
  • src/lib.rs
  • src/tools/mod.rs
  • src/tools/web.rs

Comment thread src/cli/common.rs
Comment thread src/tools/web.rs Outdated
Comment thread src/tools/web.rs Outdated
…agate parse errors, remove panics

- Normalize explicit provider config to lowercase and reject unknown values with an
  actionable error message (brave, searxng, ddg) instead of silently falling back to DDG
- Change parse_searxng_json to return Result<Vec<SearchResult>> and propagate JSON parse
  errors via ZeptoError::Tool instead of swallowing them with an empty vec
- Change SearxngSearchTool::new and with_max_results to return Result<Self>, removing
  all expect() panics from the constructor path; update call sites with ? propagation
- Update unit tests: constructor calls use .unwrap(), parse success paths use .unwrap(),
  and test_parse_searxng_results_invalid_json asserts is_err() instead of is_empty()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

web search using searxng

1 participant