feat: add Tavily as optional search backend alongside Bing scrape#67
Open
manisrinivasan2k1 wants to merge 1 commit into
Open
Conversation
QuintinShaw
requested changes
Jul 16, 2026
QuintinShaw
left a comment
Owner
There was a problem hiding this comment.
Thanks @manisrinivasan2k1 — nice idea, and the zero-config Bing fallback plus the secrets handling (key only ever sent as a Bearer header, never logged or in a URL) are both done right. A couple of things before merge:
Blocking:
npm testcurrently fails on biome (src/web-tools.ts): anoNonNullAssertionerror + a format diff, so CI won't go green. The!is actually unnecessary —@tavily/core'stavily()already falls back toprocess.env.TAVILY_API_KEYwhen you pass noapiKey, so plaintavily()drops the!; thennpx biome check --write src/web-tools.tsfor the format.- It's added via
optionalDependencies, but that doesn't make it opt-in — npm still installs it for everyone (I measured +27 packages / +25M in node_modules). Since we ship as a library, every consumer pays that even with noTAVILY_API_KEY. Could you drop the@tavily/coreentry from package.json entirely and rely purely on the dynamicimport("@tavily/core"), wrapped so a missing package gives a clear "runnpm install @tavily/core" message? That's the right shape for a truly optional backend.
Non-blocking, would be great:
- Tests for the
TAVILY_API_KEYbranch (success + error paths) — no coverage of the new logic yet. - On a Tavily error (bad key, rate limit) it hard-fails rather than falling back to Bing — either's fine, but worth a deliberate choice + a note.
- The Tavily call inherits the SDK's 60s timeout while Bing uses 15s — worth passing
{ timeout: 15 }. createTavilySearchToolis exported but never wired in — drop it or hook it up.
Happy to look again as soon as CI's green. Thanks for the contribution!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Tavily as a configurable, higher-quality search backend for the
web_searchtool. WhenTAVILY_API_KEYis present in the environment, searches are routed through the Tavily API; otherwise the existing Bing HTML scrape continues to work as before (zero-config fallback).What changed
src/web-tools.ts: Added atavilySearch()helper using dynamicimport("@tavily/core"). ModifiedcreateWebSearchTool()to checkprocess.env.TAVILY_API_KEYat call time and branch accordingly. Added a newcreateTavilySearchTool()factory for callers who want Tavily exclusively.src/index.ts: Exported the newcreateTavilySearchToolfactory.package.json: Added@tavily/coreas an optional dependency.Files changed
src/web-tools.tssrc/index.tspackage.jsonDependency changes
@tavily/core(^0.6.0) as an optional dependencyEnvironment variable changes
TAVILY_API_KEY(optional) — when set, activates Tavily backend; when absent, Bing scrape is used as beforeNotes for reviewers
import()ensures@tavily/coreis only loaded when actually needed, so environments without it installed won't break.{url, title}result shape) is unchanged — downstream consumers likedeep-researchrequire no modifications.Automated Review
createWebSearchTool()gains a runtime branch that uses Tavily whenTAVILY_API_KEYis set (falling back to Bing scrape otherwise), and a newcreateTavilySearchTool()factory is added for callers who want Tavily exclusively. The optional dependency pattern (dynamicawait import("@tavily/core")+optionalDependenciesin package.json) is the right approach. All three reported files are modified correctly, and existing behavior is fully preserved when the env var is absent. Minor issues only: no guard or clear error whencreateTavilySearchToolis called without the API key set, and the file-level JSDoc comment was not updated to mention Tavily.