Overview
The Web Search plugin enables real-time web searching using Tavily AI’s powerful search API. Get relevant, up-to-date information from across the web directly in your Nadoo workflows.
Category : Utility | Author : Nadoo Team | Version : 1.0.0 | License : MIT
Features
Real-time Search Get up-to-date information from the web
AI-Powered Tavily AI ranks results by relevance
Configurable Depth Choose between basic and advanced search
Country Filtering Filter results by country
Installation
Prerequisites
You need a Tavily API key:
Visit tavily.com
Sign up for a free account
Get your API key from the dashboard
Set Environment Variable
export TAVILY_API_KEY = "tvly-xxxxxxxxxxxxx"
Download Pre-built
# Download from releases
wget https://github.com/nadoo-ai/official-plugins/releases/download/v1.0.0/web-search-1.0.0.nadoo-plugin
# Install to workspace
nadoo-plugin install web-search-1.0.0.nadoo-plugin --workspace your-workspace-id
Build from Source
# Clone repository
git clone https://github.com/nadoo-ai/official-plugins
cd official-plugins
# Build web-search plugin
python build_plugins.py
# Install
nadoo-plugin install dist/web-search-1.0.0.nadoo-plugin --workspace your-workspace-id
search
Search the web and get relevant results.
Parameters
Parameter Type Required Default Description querystring Yes - Search query max_resultsnumber No 5 Number of results (1-20) search_depthstring No "basic"Search depth: "basic" or "advanced" countrystring No - Country filter (e.g., “south korea”, “united states”)
{
"success" : true ,
"query" : "latest AI news" ,
"results" : [
{
"title" : "Article Title" ,
"url" : "https://example.com/article" ,
"content" : "Article content snippet..." ,
"score" : 0.95
}
],
"answer" : "Direct answer to the query (if available)" ,
"images" : []
}
Usage Examples
Basic Search
from nadoo_plugin.api import ToolsClient
tools = ToolsClient(base_url, token, context)
# Simple search
result = tools.invoke(
tool_name = "web-search:search" ,
parameters = { "query" : "latest AI news" }
)
# Access results
for item in result[ "results" ]:
print ( f " { item[ 'title' ] } : { item[ 'url' ] } " )
print ( f "Relevance: { item[ 'score' ] } " )
print ( f "Content: { item[ 'content' ][: 200 ] } ..." )
Advanced Search
# More comprehensive search with advanced depth
result = tools.invoke(
tool_name = "web-search:search" ,
parameters = {
"query" : "machine learning trends 2024" ,
"max_results" : 10 ,
"search_depth" : "advanced"
}
)
# Advanced search provides:
# - More results
# - Better relevance ranking
# - Deeper analysis
Country-Specific Search
# Search within specific country
result = tools.invoke(
tool_name = "web-search:search" ,
parameters = {
"query" : "AI companies" ,
"country" : "south korea" ,
"max_results" : 5
}
)
# Get news from specific region
result = tools.invoke(
tool_name = "web-search:search" ,
parameters = {
"query" : "tech news today" ,
"country" : "united states"
}
)
In AI Agent Workflow
from nadoo_flow import BaseNode, NodeResult, NodeContext, WorkflowContext
class WebSearchNode ( BaseNode ):
"""Node that searches the web"""
def __init__ ( self ):
super (). __init__ (
node_id = "web_search" ,
node_type = "search" ,
name = "WebSearch" ,
config = {}
)
async def execute (
self ,
node_context : NodeContext,
workflow_context : WorkflowContext
) -> NodeResult:
# Get query from user input
query = node_context.input_data.get( "query" , "" )
if not query:
return NodeResult(
success = False ,
error = "No search query provided"
)
# Search the web
result = await self .call_tool(
tool_name = "web-search:search" ,
parameters = {
"query" : query,
"max_results" : 5 ,
"search_depth" : "basic"
}
)
if result.get( "success" ):
return NodeResult(
success = True ,
output = {
"query" : query,
"results" : result[ "results" ],
"answer" : result.get( "answer" )
}
)
else :
return NodeResult(
success = False ,
error = result.get( "error" , "Search failed" )
)
RAG Pattern (Search + LLM)
from nadoo_plugin.api import ToolsClient, LLMClient
class RAGSearchNode ( BaseNode ):
"""Search web and generate answer with LLM"""
async def execute (
self ,
node_context : NodeContext,
workflow_context : WorkflowContext
) -> NodeResult:
query = node_context.input_data.get( "question" )
# Step 1: Search the web
search_result = await self .call_tool(
tool_name = "web-search:search" ,
parameters = {
"query" : query,
"max_results" : 5 ,
"search_depth" : "advanced"
}
)
if not search_result.get( "success" ):
return NodeResult( success = False , error = "Search failed" )
# Step 2: Build context from search results
context = " \n\n " .join([
f "[ { i + 1 } ] { r[ 'title' ] } \n { r[ 'content' ] } "
for i, r in enumerate (search_result[ "results" ])
])
# Step 3: Generate answer with LLM
llm_result = await self .call_llm(
messages = [
{
"role" : "system" ,
"content" : "Answer based on the provided search results. Include source numbers."
},
{
"role" : "user" ,
"content" : f "Question: { query } \n\n Search Results: \n { context } "
}
]
)
return NodeResult(
success = True ,
output = {
"question" : query,
"answer" : llm_result.content,
"sources" : [
{ "title" : r[ "title" ], "url" : r[ "url" ]}
for r in search_result[ "results" ]
]
}
)
Multi-Query Search
# Search multiple topics and aggregate
queries = [
"Python async programming" ,
"FastAPI tutorials" ,
"LangChain documentation"
]
all_results = []
for query in queries:
result = tools.invoke(
tool_name = "web-search:search" ,
parameters = {
"query" : query,
"max_results" : 3
}
)
if result.get( "success" ):
all_results.extend(result[ "results" ])
# Now process all_results
Search Depth Comparison
Basic Search
Advanced Search
Best for : Quick lookups, simple queriesCharacteristics :
Faster response time
5-10 sources checked
Good for straightforward queries
Lower API cost
Use when :
You need quick results
Query is simple and well-defined
Budget is a concern
Best for : Complex research, comprehensive answersCharacteristics :
Slower but more thorough
20+ sources checked
Better for ambiguous queries
Higher API cost
Use when :
Query is complex or ambiguous
You need comprehensive coverage
Quality is more important than speed
Error Handling
result = tools.invoke(
tool_name = "web-search:search" ,
parameters = { "query" : "AI news" }
)
if result.get( "success" ):
# Process results
for item in result[ "results" ]:
print (item[ "title" ])
else :
# Handle error
error = result.get( "error" , "Unknown error" )
print ( f "Search failed: { error } " )
# Common errors:
# - "TAVILY_API_KEY not set"
# - "Invalid API key"
# - "Rate limit exceeded"
# - "Network error"
Rate Limits
Tavily API has rate limits based on your plan:
Free Tier : 1,000 requests/monthPro Tier : Higher limits availableCheck your usage at tavily.com/dashboard
Best Practices
Be specific: “Python async best practices 2024” vs “Python async”
Use keywords, not full sentences
Include context when needed
Use basic for most queries (faster, cheaper)
Use advanced for research or ambiguous queries
Monitor your API usage
Check success before processing
Use score field to rank results
Consider using top 3-5 results for context
Use RAG pattern for better answers
Let LLM synthesize information from multiple sources
Include source citations
Use Cases
Research Assistant Help users research topics with up-to-date information
News Monitoring Track latest news and trends in specific domains
Fact Checking Verify information against current web sources
Content Discovery Find relevant articles, tutorials, and resources
Troubleshooting
Error : TAVILY_API_KEY environment variable not setSolution :export TAVILY_API_KEY = "your-key-here"
Error : Invalid API keySolution :
Verify your API key at tavily.com
Ensure no extra spaces or quotes
Check if key is active
Error : Rate limit exceededSolution :
Wait before retrying
Upgrade your Tavily plan
Implement caching to reduce calls
Error : Empty results arraySolution :
Try different query phrasing
Use more general terms
Check if topic is too niche
Contributing
Want to improve this plugin? Contributions welcome!
Fork official-plugins
Make your changes to web-search/main.py
Test with your Tavily API key
Submit a pull request
License
MIT License - Nadoo Team
Support