Skip to content

fix(tools): make web_search resilient via multi-engine fallback (#231)#232

Merged
warren618 merged 1 commit into
mainfrom
fix/web-search-multi-backend
Jun 15, 2026
Merged

fix(tools): make web_search resilient via multi-engine fallback (#231)#232
warren618 merged 1 commit into
mainfrom
fix/web-search-multi-backend

Conversation

@warren618

Copy link
Copy Markdown
Collaborator

Summary

Makes web_search resilient to single-engine rate limiting. Fixes #231, where the tool showed a red ❌ "web search failure" while the run still completed via read_url — the symptom of DuckDuckGo (the default ddgs auto backend's lead engine) being throttled from cloud/shared IPs.

Why

ddgs is a metasearch aggregator (DuckDuckGo, Google, Bing, Brave, Mojeek, Yahoo, …), all key-free. The previous code relied on the default backend="auto", which leads with DuckDuckGo; when DDG threw, the whole tool returned an error even though the other engines were reachable. (Reproduced: the duckduckgo backend returns "No results found." intermittently while google/bing/brave/mojeek succeed for the same query.)

Changes

  • Pass an explicit ordered backend list (duckduckgo, google, bing, brave, mojeek, yahoo) so ddgs falls through a throttled engine to the next. Overridable via VIBE_TRADING_SEARCH_BACKENDS (e.g. pin to google, bing).
  • Retry transient failures with linear backoff (3 attempts).
  • Treat "No results found" as an ok + empty-results envelope, not an error.
  • On persistent failure, return an actionable message (retry / set the backend env / use read_url) instead of a bare exception string.
  • Report the backend list used in the ok envelope.
  • Preserves the legacy duckduckgo_search fallback (calls without the backend kwarg when ddgs isn't present).

Test Plan

  • New agent/tests/test_web_search_tool.py — 6 cases (mocked ddgs): multi-backend pass-through, env override, retry-then-succeed, no-results→ok-empty, persistent-failure message, max_results cap. All pass.
  • Live smoke against real ddgs returns results across the backend list.
  • Existing regression touching web_search (security scanner + MCP regression) passes; tool registry still discovers web_search (48 tools).

Checklist

  • No changes to protected areas (src/agent/, src/session/, src/providers/)
  • No hardcoded values (backend list is env-overridable)
  • Code follows CONTRIBUTING.md guidelines

web_search relied on ddgs's default 'auto' backend, which leads with
DuckDuckGo — heavily rate-limited from cloud/shared IPs. When DDG
threw, the whole tool returned ❌ (issue #231) even though Google/
Bing/Brave/Mojeek/Yahoo were reachable.

- Pass an explicit ordered backend list so ddgs falls through a
  throttled engine to the next; override via VIBE_TRADING_SEARCH_BACKENDS
- Retry transient failures with linear backoff (3 attempts)
- Treat "No results found" as an ok+empty envelope, not an error
- On persistent failure, return an actionable message (retry / set
  backend env / use read_url) instead of a bare exception string
- Report the backend list used in the ok envelope

Tests: new tests/test_web_search_tool.py (6 cases, mocked ddgs) cover
multi-backend pass-through, env override, retry-then-succeed,
no-results, persistent-failure message, and max_results cap.
@warren618 warren618 merged commit a1d84b5 into main Jun 15, 2026
1 check passed
@warren618 warren618 deleted the fix/web-search-multi-backend branch June 15, 2026 09:06
@warren618 warren618 mentioned this pull request Jun 15, 2026
@warren618 warren618 mentioned this pull request Jun 18, 2026
7 tasks
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.

[Bug]

1 participant