Skip to content

Conversation

@divyeshradadiya
Copy link
Contributor

SERPEX Search Tool Integration - PR Description

Description

This PR adds SERPEX integration as a search tool for LlamaIndex, enabling AI agents and RAG applications to access real-time web search results from multiple search engines.

SERPEX provides a simple, fast API for web search results with support for Google, Bing, DuckDuckGo, Brave, Yahoo, and Yandex search engines.

Motivation

  • Enables LlamaIndex users to add web search capabilities to their AI agents
  • Perfect for RAG (Retrieval-Augmented Generation) applications
  • Provides current information to LLM applications
  • Simple integration with LlamaIndex's tool framework
  • Multi-engine support for flexibility and reliability

Changes Made

  1. New Package: llama-index-tools-serpex

    • Located in: llama-index-integrations/tools/llama-index-tools-serpex/
    • Implements SerpexToolSpec class for easy integration
  2. Features:

    • ✨ Multi-engine support (auto, google, bing, duckduckgo, brave, yahoo, yandex)
    • ⏰ Time range filtering (all, day, week, month, year)
    • 🔍 Clean, formatted search results as LlamaIndex Documents
    • 🛡️ Robust error handling
    • 📦 Easy integration with LlamaIndex agents
  3. Testing:

    • 8 unit tests with mocked API responses
    • 2 integration tests for real API verification
    • All tests passing locally
    • Manual verification with real SERPEX API
  4. Code Quality:

    • Formatted with black
    • Linted with ruff (all checks passing)
    • Type hints included
    • Comprehensive docstrings
  5. Documentation:

    • README with installation and usage
    • Example code in examples/serpex_example.py
    • Inline documentation and docstrings
    • Integration guide

Fixes

N/A - This is a new feature addition.


New Package?

  • Yes - Created llama-index-tools-serpex
  • Filled in tool.llamahub section in pyproject.toml
  • Provided detailed README.md

Details:

  • Package name: llama-index-tools-serpex
  • Version: 0.1.0
  • Description: SERPEX search tool integration for LlamaIndex
  • Keywords: search, serpex, google, web-search

Version Bump?

  • Yes - Version 0.1.0 for new package
  • Updated in pyproject.toml

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • I added new unit tests to cover this change
  • Unit Test Coverage: 8 tests passing
  • Integration Tests: 2 tests (skipped in CI, require API key)
  • Manual Testing: Verified with real SERPEX API

Test Results

======================================================================== test session starts ========================================================================
platform darwin -- Python 3.9.6, pytest-7.2.1, pluggy-1.6.0
collected 10 items

tests/test_serpex.py::test_serpex_init_with_key PASSED                                                                                                        [ 10%]
tests/test_serpex.py::test_serpex_init_with_custom_engine PASSED                                                                                              [ 20%]
tests/test_serpex.py::test_serpex_init_without_key PASSED                                                                                                     [ 30%]
tests/test_serpex.py::test_search PASSED                                                                                                                      [ 40%]
tests/test_serpex.py::test_search_with_engine PASSED                                                                                                          [ 50%]
tests/test_serpex.py::test_search_with_time_range PASSED                                                                                                      [ 60%]
tests/test_serpex.py::test_search_no_results PASSED                                                                                                           [ 70%]
tests/test_serpex.py::test_search_api_error PASSED                                                                                                           [ 80%]
tests/test_serpex.py::test_real_search SKIPPED (Requires real SERPEX API key)                                                                                 [ 90%]
tests/test_serpex.py::test_real_search_with_filters SKIPPED (Requires real SERPEX API key)                                                                    [100%]

================================================================ 8 passed, 2 skipped, 2 warnings in 0.66s ================================================================

Manual Verification

  • ✅ Real API test with SerpexToolSpec()
  • ✅ Search with multiple engines works
  • ✅ Time range filtering works
  • ✅ Error handling works
  • ✅ Results formatted correctly as Documents

Checklist

Code Review

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My code follows the project's style guidelines (black + ruff)

Documentation

  • I have made corresponding changes to the documentation
  • README.md provided with installation and usage instructions
  • Docstrings with type hints included
  • Example code in examples/serpex_example.py

Testing

  • I have added tests that prove my feature works
  • New and existing unit tests pass locally with my changes
  • All 8 unit tests pass
  • 2 integration tests included (skipped without API key)

Formatting & Linting

  • I ran uv run make format; uv run make lint to appease the lint gods
  • Formatted with black
  • All ruff checks passing
  • No new warnings generated

LlamaHub Compliance

  • New package section in pyproject.toml filled
  • README.md provided
  • Installation instructions included
  • Example usage provided

Files Changed

New Files

llama-index-integrations/tools/llama-index-tools-serpex/
├── README.md
├── LICENSE
├── Makefile
├── pyproject.toml
├── .gitignore
├── llama_index/
│   └── tools/
│       └── serpex/
│           ├── __init__.py
│           └── base.py
├── tests/
│   └── test_serpex.py
└── examples/
    └── serpex_example.py

Statistics

  • Total Lines of Code: ~500
  • Test Coverage: 100% of public API
  • Documentation: Complete

Installation

After merge, users can install via:

pip install llama-index-tools-serpex

Usage Example

from llama_index.tools.serpex import SerpexToolSpec
from llama_index.agent.openai import OpenAIAgent
import os

# Set API key
os.environ["SERPEX_API_KEY"] = "your_api_key"

# Initialize tool
serpex_tool = SerpexToolSpec()

# Create agent with tool
agent = OpenAIAgent.from_tools(
    serpex_tool.to_tool_list(),
    verbose=True
)

# Use agent for web search
response = agent.chat("What are the latest developments in AI?")
print(response)

API Details

  • Endpoint: https://api.serpex.dev/api/search

  • Method: GET

  • Parameters:

    • q (required): Search query
    • engine (optional): Search engine (auto, google, bing, duckduckgo, brave, yahoo, yandex)
    • category (optional): Search category (web)
    • time_range (optional): Time filter (all, day, week, month, year)
  • Get API Key: https://serpex.dev/dashboard


Dependencies

  • llama-index-core>=0.14.0
  • requests>=2.31.0

No new external dependencies beyond what's already used in LlamaIndex.


Related Issues

N/A - This is a new feature.


Additional Notes

  • All code follows LlamaIndex conventions and patterns
  • Uses LlamaIndex's BaseToolSpec for compatibility
  • Returns results as Document objects for consistency
  • Fully compatible with LlamaIndex agents and workflows
  • Ready for production use

CC

@run-llama/maintainers

Thank you for reviewing this contribution! 🎉

@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Oct 24, 2025
- Add SerpexToolSpec for web search via SERPEX API
- Support multiple search engines (Google, Bing, DuckDuckGo, Brave, Yahoo, Yandex)
- Include time range filtering (day, week, month, year)
- Add comprehensive unit tests with mocked API responses
- Add integration tests for real API verification
- Include documentation and usage examples
- Format with black and pass ruff linting
- API endpoint: https://api.serpex.dev/api/search
- All tests passing (8 passed, 2 skipped)
@divyeshradadiya divyeshradadiya force-pushed the feat/serpex-tool-integration branch from 4036c75 to c2c8903 Compare October 24, 2025 10:31
Copy link
Member

@AstraBert AstraBert left a comment

Choose a reason for hiding this comment

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

Looks overall good, I just have some doubts about the implementation and some things I would change (see comments below 👇)

results_list = data.get("results", [])

if not results_list:
return [Document(text="No search results found.")]
Copy link
Member

Choose a reason for hiding this comment

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

I would return an empty string, this could be misleading if someone just checked len(result) > 0 before returning to the user


except requests.exceptions.RequestException as e:
error_msg = f"Error calling SERPEX API: {str(e)}"
return [Document(text=error_msg)]
Copy link
Member

Choose a reason for hiding this comment

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

I would raise the error and not return a list with one document (could be misleading for the same reason as above)

Comment on lines 157 to 164
# Add metadata
metadata = data.get("metadata", {})
if metadata:
num_results = metadata.get("number_of_results", 0)
response_time = metadata.get("response_time", 0)
results_text += (
f"\n\n(Found {num_results} results in {response_time}ms)"
)
Copy link
Member

Choose a reason for hiding this comment

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

Couldn't we just add these in the document metadata?

Comment on lines 154 to 156
results_text = f"Search results for '{query}':\n\n"
results_text += "\n".join(formatted_results)

Copy link
Member

Choose a reason for hiding this comment

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

is there a reason why we return a single document with all the results instead of multiple documents?



# Integration test (requires real API key)
@pytest.mark.skip(reason="Requires real SERPEX API key")
Copy link
Member

Choose a reason for hiding this comment

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

Can we put skipif here and verify the absence of the key before skipping? In CI here on GitHub there is no difference, but if one would want to test locally, this would be skipped whether or not the key is available in the environment

@divyeshradadiya
Copy link
Contributor Author

divyeshradadiya commented Oct 29, 2025

@AstraBert Thanks for the suggestions! I've made the changes you mentioned. Could you review it now?

Copy link
Member

@AstraBert AstraBert left a comment

Choose a reason for hiding this comment

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

lgtm

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Oct 29, 2025
@AstraBert AstraBert enabled auto-merge (squash) October 29, 2025 10:31
auto-merge was automatically disabled October 29, 2025 11:15

Head branch was pushed to by a user without write access

@AstraBert AstraBert enabled auto-merge (squash) October 29, 2025 11:40
@AstraBert AstraBert merged commit 9892870 into run-llama:main Oct 29, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants