feat(tools): add SearchApi tool with multi-engine support#6434
feat(tools): add SearchApi tool with multi-engine support#6434axiom-of-choice wants to merge 3 commits into
Conversation
Add SearchApiSearchTool supporting 7 search engines (google, google_news, google_shopping, google_jobs, youtube, bing, baidu) through a single configurable tool class. Key design decisions: - Single tool with engine parameter vs separate classes per engine - Bearer token auth with PrivateAttr to prevent key serialization leaks - Per-query location parameter for runtime flexibility - Comprehensive test suite (19 tests) covering initialization, request construction, multi-engine execution, and error handling
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds a new ChangesSearchApi Search Tool
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Per CONTRIBUTING.md: this PR was authored with AI assistance. Please apply the I don't have permission to add labels as an external contributor. |
Live API EvidenceTested against SearchApi.io with real API key across 4 engines: Google Search{
"organic_results": [
{
"position": 1,
"title": "CrewAI",
"link": "https://crewai.com/",
"snippet": "Build. Deploy. Manage. Enterprise Agents..."
}
]
}Google News{
"organic_results": [
{
"position": 1,
"title": "Latin America and the Caribbean Consolidate a Regional Roadmap for...",
"source": "UNESCO",
"date": "4 hours ago"
}
]
}Google Shopping{
"shopping_results": [
{
"title": "Keychron Q1 HE...",
"price": "$219.00",
"source": "Keychron"
}
]
}YouTube{
"videos": [
{
"position": 1,
"title": "Python Full Course for Beginners",
"link": "https://www.youtube.com/watch?v=K5KVEU3aaeQ",
"views": 6769124,
"channel": {"title": "Programming with Mosh"}
}
]
}All 4 engines return structured, clean results. Metadata fields ( Unit tests: 19/19 passing ( |
|
Hey @lorenzejay @vinibrsl — would appreciate a review when you get a chance. This is an alternative approach to #6378 with multi-engine support (7 engines via a single class) and comprehensive tests. Happy to adjust anything. Feel free to also tag another maintainer to review and untag yourself |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/crewai-tools/src/crewai_tools/__init__.py`:
- Around line 163-165: `SearchApiSearchTool` is imported in
`crewai_tools/__init__.py` but not exposed in the module’s `__all__`, so update
the `__all__` list in that same file to include `SearchApiSearchTool` in the
existing alphabetical order. Keep the import and public export definitions
aligned with `tools/__init__.py` so `from crewai_tools import *` and
`__all__`-based tooling include this symbol.
In `@lib/crewai-tools/src/crewai_tools/tools/searchapi_tool/README.md`:
- Around line 13-14: The README tables under the Supported Engines and other
headings are missing the required blank line before the table, triggering MD058.
Update the markdown in this README so each table is separated from its preceding
heading by a single empty line, keeping the table content unchanged. Use the
nearby heading/table pairs in the SearchAPI tool README to locate and fix all
affected spots, including the other referenced table sections.
In
`@lib/crewai-tools/src/crewai_tools/tools/searchapi_tool/searchapi_search_tool.py`:
- Around line 66-86: The engine check in SearchApiTool is only happening inside
__init__, so assignment-time validation is bypassed even though
validate_assignment=True is enabled. Move the engine membership check into a
field_validator for the engine field in SearchApiTool so it runs on both
construction and later assignments, and keep the same ValueError text for
compatibility with existing tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d2887d4f-2e7b-484c-af9e-34675125387c
📒 Files selected for processing (7)
lib/crewai-tools/src/crewai_tools/__init__.pylib/crewai-tools/src/crewai_tools/tools/__init__.pylib/crewai-tools/src/crewai_tools/tools/searchapi_tool/README.mdlib/crewai-tools/src/crewai_tools/tools/searchapi_tool/__init__.pylib/crewai-tools/src/crewai_tools/tools/searchapi_tool/searchapi_search_tool.pylib/crewai-tools/tests/tools/searchapi_tool_test.pylib/crewai-tools/tool.specs.json
- Add SearchApiSearchTool to __all__ in crewai_tools/__init__.py - Fix MD058: add blank lines before tables in README - Move engine validation to field_validator for assignment-time checks


Summary
Adds
SearchApiSearchTool— a single tool class that supports 7 search engines (google, google_news, google_shopping, google_jobs, youtube, bing, baidu) via SearchApi.io's unified SERP API.Design
One configurable tool instead of one class per engine. Users pick the engine at init time:
Location can be passed per-query at runtime for maximum flexibility.
Why a single tool class?
SearchApi's differentiator is one endpoint for 100+ engines — the tool design should reflect that. Separate classes per engine would mean adding a new file every time you want to support a new engine. With this design, adding a new engine is one line in
SUPPORTED_ENGINES.Relation to #6378
I'm aware of the existing PR. This takes a different architectural approach (single configurable class vs. separate per-engine classes) and adds:
locationparameter in the schema (agents can pass location per-query)country,language, andn_resultsconfigurationPrivateAttrto prevent serialization leaksTest results
Tests cover:
Checklist
feat/searchapi-toolruff checkpassesruff formatpassesmypypasses with no issuestool.specs.jsonupdated__init__.pyfiles