Package com.tnsai.tools.search
Class WebSearchTools
java.lang.Object
com.tnsai.tools.search.WebSearchTools
Function-shape web search tools — the LangChain-style replacement for the
legacy
DuckDuckGoTool, WikipediaTool, etc. (see issue #188).
This POJO grows method-by-method across Phase 2 batches as each legacy search engine is migrated:
| Method | Replaces | API key |
|---|---|---|
duckduckgo(java.lang.String) | DuckDuckGoTool | none |
wikipedia(java.lang.String, int, java.lang.String) | WikipediaTool | none |
Subsequent sub-batches (4b, 4c) will append brave, serpapi,
tavily, exa, searxng, wikidata, npm,
maven_central, hackernews, stackoverflow methods to
this same POJO. Per-API constructor injection lands together with the first
key-bearing method (planned: 4b — Brave + SerpApi + Tavily + Exa).
Threading
The shared OkHttpClient and ObjectMapper fields are
thread-safe; instances of this POJO can therefore be shared across roles
and concurrent dispatches without synchronisation.
- Since:
- 0.5.7 (Phase 2 batch 4 — built-in tool migration to function shape, see #188)
-
Constructor Summary
ConstructorsConstructorDescriptionDefault constructor — picks API keys up from environment variables and uses a 15-second-per-call OkHttp client.WebSearchTools(String braveApiKey, String serpApiKey, String tavilyApiKey, String exaApiKey) Explicit-keys constructor — for DI containers, multi-tenant deployments where each tenant carries its own API keys, or test scaffolds.WebSearchTools(String braveApiKey, String serpApiKey, String tavilyApiKey, String exaApiKey, okhttp3.OkHttpClient http, com.fasterxml.jackson.databind.ObjectMapper mapper) Full constructor — for tests that need to inject aURL or share an OkHttp client with the rest of the application.invalid reference
MockWebServer -
Method Summary
-
Constructor Details
-
WebSearchTools
public WebSearchTools()Default constructor — picks API keys up from environment variables and uses a 15-second-per-call OkHttp client. This is theRole.tools()"just give me everything" entry point. Engines whose env var is unset stay configured but their tool methods raiseIllegalStateExceptionwith a clear "missing key" message when the LLM tries to call them.Engine Env var Brave Search BRAVE_API_KEYSerpApi SERPAPI_API_KEYTavily TAVILY_API_KEYExa EXA_API_KEY -
WebSearchTools
Explicit-keys constructor — for DI containers, multi-tenant deployments where each tenant carries its own API keys, or test scaffolds. Passnullfor any engine you don't want to expose; that engine's tool method then raisesIllegalStateExceptionon call rather than dispatching with a missing credential. -
WebSearchTools
public WebSearchTools(String braveApiKey, String serpApiKey, String tavilyApiKey, String exaApiKey, okhttp3.OkHttpClient http, com.fasterxml.jackson.databind.ObjectMapper mapper) Full constructor — for tests that need to inject aURL or share an OkHttp client with the rest of the application. The POJO does not own the HTTP client's lifecycle.invalid reference
MockWebServer
-
-
Method Details
-
duckduckgo
@Tool(name="duckduckgo", description="Query the DuckDuckGo Instant Answer API for definitions, general knowledge, and factual lookups. No API key needed. Best for: \'what is X\', \'who is Y\', encyclopedic facts. Returns a structured Markdown summary with up to 5 related topics, or a \'no instant answers\' message if the API has nothing for the query (common for news / sports / real-time queries \u2014 try a web search engine instead).", keywords={"search","duckduckgo","ddg","definition","fact","knowledge"}, idempotent=true) public String duckduckgo(@ToolParam(description="The natural-language search query") String query) throws IOException - Throws:
IOException
-
wikipedia
@Tool(name="wikipedia", description="Search Wikipedia via the MediaWiki API and return the top matching article titles + snippets. Returns the language edition\'s results (default English). No API key needed. Use this for encyclopedic depth \u2014 biographies, history, concepts. For real-time events / news, use a web search engine instead.", keywords={"search","wikipedia","wiki","encyclopedia","knowledge","biography"}, idempotent=true) public String wikipedia(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="Number of results (1..50; defaults to 5)",required=false,defaultValue="5") int limit, @ToolParam(description="Wikipedia language code (e.g. \"en\", \"tr\", \"de\"); defaults to \"en\"",required=false,defaultValue="en") String language) throws IOException - Throws:
IOException
-
brave
@Tool(name="brave_search", description="Web search via the Brave Search API \u2014 fast, privacy- respecting, and good general-purpose recall including news / sports / real-time topics. Requires BRAVE_API_KEY. Returns a Markdown-formatted list of result titles, URLs, and short descriptions.", keywords={"search","brave","web","news"}, idempotent=true) public String brave(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="Number of results (1..20; defaults to 5)",required=false,defaultValue="5") int count) throws IOException - Throws:
IOException
-
serpapi
@Tool(name="serpapi", description="Google search results via SerpApi (paid). Useful for complex queries where you want Google\'s relevance ranking \u2014 Knowledge Graph, answer boxes, organic results, and \"People Also Ask\" sections all parsed in one call. Requires SERPAPI_API_KEY.", keywords={"search","google","serpapi","serp"}, idempotent=true) public String serpapi(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="SerpApi engine \u2014 \"google\" (default), \"bing\", \"duckduckgo\", \"yahoo\", \"baidu\", \"yandex\"",required=false,defaultValue="google") String engine) throws IOException - Throws:
IOException
-
tavily
@Tool(name="tavily", description="AI-optimized search via the Tavily API. Best for research-quality results: returns an LLM-summarized answer plus the source documents the answer is grounded in, all in one call. Requires TAVILY_API_KEY.", keywords={"search","tavily","ai","research","rag"}, idempotent=true) public String tavily(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="Search depth \u2014 \"basic\" (default, faster) or \"advanced\" (deeper crawl, slower)",required=false,defaultValue="basic") String depth) throws IOException - Throws:
IOException
-
exa
@Tool(name="exa", description="Neural search via Exa (formerly Metaphor). Built specifically for LLM use cases \u2014 returns highlights and extracted text alongside URLs, with optional autoprompt for query refinement. Requires EXA_API_KEY.", keywords={"search","exa","neural","metaphor","highlights","rag"}, idempotent=true) public String exa(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="Number of results (1..25; defaults to 10)",required=false,defaultValue="10") int numResults) throws IOException - Throws:
IOException
-
wikidata
@Tool(name="wikidata", description="Query Wikidata for structured-knowledge entities (people, places, concepts, \u2026) and return their QID, label, and short description. Returns up to {limit} matches in the requested language. No API key needed. Useful when you want canonical IDs to follow up with SPARQL queries against the Wikidata Query Service.", keywords={"search","wikidata","knowledge","entity","qid","linked-data"}, idempotent=true) public String wikidata(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="Number of results (1..50; defaults to 5)",required=false,defaultValue="5") int limit, @ToolParam(description="Wikidata language code (e.g. \"en\", \"tr\", \"de\"); defaults to \"en\"",required=false,defaultValue="en") String language) throws IOException - Throws:
IOException
-
searxng
@Tool(name="searxng", description="Self-hosted meta-search via a SearXNG instance. Aggregates multiple search engines without tracking. {instance} accepts any SearXNG public or private instance URL; defaults to https://searx.be. {categories} narrows the search (\"general\", \"images\", \"news\", \"science\", \"social media\", \u2026); defaults to \"general\".", keywords={"search","searxng","self-hosted","meta-search","privacy"}, idempotent=true) public String searxng(@ToolParam(description="The natural-language search query") String query, @ToolParam(description="SearXNG instance base URL (no trailing /); defaults to https://searx.be",required=false,defaultValue="https://searx.be") String instance, @ToolParam(description="Comma-separated categories (general/images/news/science/\u2026); defaults to \"general\"",required=false,defaultValue="general") String categories, @ToolParam(description="Language code or \"auto\"; defaults to \"auto\"",required=false,defaultValue="auto") String language) throws IOException - Throws:
IOException
-
npm
@Tool(name="npm", description="Search the public npm registry for JavaScript / TypeScript packages. No API key needed. Returns up to 10 matches with name, version, description, publisher, and keywords.", keywords={"search","npm","package","javascript","typescript","node"}, idempotent=true) public String npm(@ToolParam(description="Package-search query (name, keyword, or description fragment)") String query) throws IOException - Throws:
IOException
-
mavenCentral
@Tool(name="maven_central", description="Search Maven Central for Java artifacts. No API key needed. Returns up to 10 matches with groupId, artifactId, latest version, packaging type, and Maven Central URL.", keywords={"search","maven","central","java","artifact","dependency"}, idempotent=true) public String mavenCentral(@ToolParam(description="Maven Central search query (artifact name, group, or full coordinate fragment)") String query) throws IOException - Throws:
IOException
-