Skip to content
This repository was archived by the owner on Nov 10, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crewai_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
TavilyExtractorTool,
TavilySearchTool,
TXTSearchTool,
YouSearchTool,
VisionTool,
WeaviateVectorSearchTool,
WebsiteSearchTool,
Expand Down
1 change: 1 addition & 0 deletions crewai_tools/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
)
from .youtube_video_search_tool.youtube_video_search_tool import YoutubeVideoSearchTool
from .zapier_action_tool.zapier_action_tool import ZapierActionTools
from .you_search_tool.you_search_tool import YouSearchTool
from .parallel_tools import (
ParallelSearchTool,
)
89 changes: 89 additions & 0 deletions crewai_tools/tools/you_search_tool/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# YouSearchTool (You.com Search API)

Simple wrapper for the You.com Search API that returns structured web/news results with snippets and URLs.

Docs:
- Search API (Trusted, Recent info): https://documentation.you.com/api-modes/search-api#trustworthy-and-recent-informantion-for-your-research
- Quickstart (Search API): https://documentation.you.com/docs/quickstart#search-api

## What it's for

Use when you need accurate, up-to-date web snippets and URLs from trusted sources to ground agent answers without extra scraping. Results include long snippets, titles, and links suitable for direct LLM consumption.

## Environment

- YOU_API_KEY (required) — used as `X-API-Key`

## Parameters

- `query` (str, required): Natural‑language search query. Returns structured results (web/news) with snippets and URLs.

## Usage (published)

```python
from crewai_tools import YouSearchTool

you = YouSearchTool()
resp = you.run(query="result of the political debate in EU")
print(resp) # JSON string containing results.web/news arrays
```

## Example with agents

Here’s a minimal CrewAI agent that uses `YouSearchTool` as a tool. The agent will invoke the tool directly (no manual `run(...)` calls).

```python
import os
from crewai import Agent, Task, Crew, LLM, Process
from crewai_tools import YouSearchTool

# LLM (configure your provider keys, e.g., GEMINI_API_KEY or OPENAI_API_KEY)
llm = LLM(
model="gemini/gemini-2.0-flash",
temperature=0.5,
api_key=os.getenv("GEMINI_API_KEY")
)

# You.com Web Search Tool
you = YouSearchTool()

# User query
query = "all the recent CrewAI news"

researcher = Agent(
role="Senior Web Researcher",
backstory="You are an expert web researcher.",
goal="Find cited, high-quality sources and provide a detailed answer.",
tools=[you],
llm=llm,
verbose=True,
)

# Research task
task = Task(
description="""Use the You.com Web Search tool to research: {query}.
Provide the answer in detail and cite sources (sources should be in the format of [source](url)).""",
expected_output="A detailed, sourced answer to the question.",
agent=researcher,
output_file="answer.md",
)

# Crew
crew = Crew(
agents=[researcher],
tasks=[task],
verbose=True,
process=Process.sequential,
)

# Kickoff the crew
result = crew.kickoff(inputs={'query': query})
print(result)
```

## Notes

- Endpoint: `GET https://api.ydc-index.io/v1/search` with headers `{ "X-API-Key": YOU_API_KEY }` and params `{ query: ... }`
- Returns results grouped by sections (e.g., `results.web`, `results.news`) with URLs, titles, descriptions, and snippets.


60 changes: 60 additions & 0 deletions crewai_tools/tools/you_search_tool/you_search_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import os
from typing import Any, Dict, Optional, Type

import requests
from typing import List
from crewai.tools import BaseTool, EnvVar
from pydantic import BaseModel, Field


class YouSearchToolSchema(BaseModel):
"""Input for You.com Web Search."""

query: str = Field(..., description="Search query text")


class YouSearchTool(BaseTool):
name: str = "You.com Web Search Tool"
description: str = (
"Perform a web search using You.com's Search API and return structured results "
"(web/news) with snippets and URLs."
)
args_schema: Type[BaseModel] = YouSearchToolSchema

env_vars: List[EnvVar] = [
EnvVar(
name="YOU_API_KEY",
description="API key for You.com Search API (used as X-API-Key)",
required=True,
)
]
package_dependencies: List[str] = ["requests"]

base_url: str = "https://api.ydc-index.io/v1/search"

def _run(self, query: str, **_: Any) -> str:
api_key = os.environ.get("YOU_API_KEY")
if not api_key:
return "Error: YOU_API_KEY environment variable is required"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we raise error ?


headers = {"X-API-Key": api_key}
params: Dict[str, Any] = {"query": query}

try:
resp = requests.get(self.base_url, headers=headers, params=params, timeout=20)
if resp.status_code >= 300:
return f"You.com Search API error: {resp.status_code} {resp.text[:200]}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same here?

data = resp.json()
# Return JSON string so agents can consume directly
try:
import json

return json.dumps(data, ensure_ascii=False)
except Exception:
return str(data)
except requests.Timeout:
return "You.com Search API timeout. Please try again later."
except Exception as exc: # noqa: BLE001
return f"Unexpected error calling You.com Search API: {exc}"


40 changes: 40 additions & 0 deletions tests/tools/you_search_tool_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from unittest.mock import patch

import pytest

from crewai_tools.tools.you_search_tool.you_search_tool import YouSearchTool


def test_requires_env_var(monkeypatch):
monkeypatch.delenv("YOU_API_KEY", raising=False)
tool = YouSearchTool()
result = tool.run(query="test")
assert "YOU_API_KEY" in result


@patch("crewai_tools.tools.you_search_tool.you_search_tool.requests.get")
def test_happy_path(mock_get, monkeypatch):
monkeypatch.setenv("YOU_API_KEY", "test")

mock_get.return_value.status_code = 200
mock_get.return_value.json.return_value = {
"results": {
"web": [
{
"url": "https://www.europarl.europa.eu/topics/en/topic/state-of-the-eu-debates",
"title": "State of the EU debates",
"snippets": [
"MEPs will scrutinise the work of the European Commission..."
],
}
]
},
"metadata": {"query": "result of the political debate in EU"},
}

tool = YouSearchTool()
result = tool.run(query="result of the political debate in EU")
assert "results" in result
assert "europarl.europa.eu" in result


Loading