Skip to content

feat: add Tavily as configurable search backend alongside DuckDuckGo#22

Open
tavily-integrations wants to merge 1 commit into
demigodmode:mainfrom
Tavily-FDE:feat/tavily-migration/duckduckgo-web-search
Open

feat: add Tavily as configurable search backend alongside DuckDuckGo#22
tavily-integrations wants to merge 1 commit into
demigodmode:mainfrom
Tavily-FDE:feat/tavily-migration/duckduckgo-web-search

Conversation

@tavily-integrations
Copy link
Copy Markdown

Summary

Adds Tavily as a parallel/fallback search backend alongside the existing DuckDuckGo HTML scraping approach. DuckDuckGo scraping is prone to blocks and CAPTCHAs; Tavily provides a reliable API-backed alternative.

What changed

  • New file src/search/tavily.ts: Wraps the @tavily/core SDK search() call, mapping results to the shared SearchResult[] type.
  • src/types.ts: Extended SearchMetadata.backend union from 'duckduckgo' to 'duckduckgo' | 'tavily'.
  • src/tools/web-search.ts: Added backend option ('duckduckgo' | 'tavily' | 'auto', default 'auto') to createWebSearchTool. In 'auto' mode, DuckDuckGo is attempted first; on BLOCKED or PARSE_FAILED errors, Tavily is used as fallback when TAVILY_API_KEY is available. Extracted searchWithDuckDuckGo and searchWithTavily helper functions.
  • package.json: Added @tavily/core as a production dependency.

Files changed

  • src/search/tavily.ts (new)
  • src/types.ts
  • src/tools/web-search.ts
  • package.json

Dependency changes

  • Added @tavily/core ^0.6.0 to production dependencies

Environment variable changes

  • TAVILY_API_KEY: Required when using backend: 'tavily'; optional in 'auto' mode (DuckDuckGo remains the default, Tavily used as fallback only when the key is present)

Notes for reviewers

  • No breaking changes — existing callers using default options get the same DuckDuckGo-first behavior with automatic Tavily fallback when TAVILY_API_KEY is set.
  • The SearchBackend type is exported for consumers who want to explicitly select a backend.
  • TypeScript compilation passes cleanly with tsc --noEmit.

Automated Review

  • Passed after 1 attempt(s)
  • Final review: The implementation correctly adds Tavily as a configurable/fallback search backend alongside DuckDuckGo. All four files listed in the plan are addressed: src/search/tavily.ts (new), src/types.ts, src/tools/web-search.ts, and package.json/package-lock.json. The Tavily SDK usage is correct, the auto fallback logic is sound, no breaking changes are introduced, and existing tests remain valid. There are a few minor issues (hardcoded backend in invalid-query error, missing tests for new paths, no README env-var docs) but none rise to major or critical severity.

Copy link
Copy Markdown
Owner

@demigodmode demigodmode left a comment

Choose a reason for hiding this comment

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

Thanks for opening this. I like the direction, but I don't think this is ready to merge as-is.

Main blockers:

  • This branch conflicts with current main now that v1.0.0 landed. It needs a rebase/update, especially around package.json, package-lock.json, and the typebox migration.
  • The new behavior doesn't have tests. This changes the core search path, so we need coverage for at least:
    • backend = tavily success and failure
    • backend = auto using DuckDuckGo when it succeeds
    • backend = auto falling back to Tavily on BLOCKED / PARSE_FAILED when TAVILY_API_KEY is present
    • no fallback when the key is absent
    • empty-query metadata for non-DuckDuckGo backends
  • The empty-query path still hardcodes metadata.backend = duckduckgo, even when the tool is configured for Tavily. Small bug, but it shows the backend state isn't fully threaded through.

Design questions before this lands:

  • Do we want to add @tavily/core as a hard runtime dependency for everyone, or should this be optional/dynamic since most users won't have TAVILY_API_KEY configured?
  • If Tavily is meant to be user-configurable, this probably needs to connect to /web-agent config or docs. Right now it is only configurable by code via createWebSearchTool, not by normal pi-web-agent users.

Overall: useful feature, but please rebase against current main and add tests for the new backend/fallback behavior before merge.

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.

2 participants