"""
title: Brave Web Search Tool
description: Tool to perform web search via Brave Search API
author: GrimTM
version: 1.0.0
"""
import aiohttp
import asyncio
from typing import Any, Optional, Callable, Awaitable
from pydantic import BaseModel
class Tools:
class UserValves(BaseModel):
"""Insert your Brave Search API key here if needed"""
pass
def __init__(self):
self.api_key = "YOUR_BRAVE_API_KEY" # Replace with your actual API key
self.base_url = "https://api.search.brave.com/res/v1/web/search"
self.max_results = 5
async def search_web(
self,
topic: str,
__user__: dict = {},
__event_emitter__: Optional[Callable[[Any], Awaitable[None]]] = None,
) -> str:
"""
Perform a web search using Brave Search API and return formatted results.
Args:
topic: The search topic or query string.
Returns:
A formatted string of search results with titles, URLs, and snippets.
"""
if __event_emitter__:
await __event_emitter__(
{
"type": "status",
"data": {"description": "Searching the web via Brave...", "done": False},
}
)
try:
headers = {
"Accept": "application/json",
"X-Subscription-Token": self.api_key,
}
params = {"q": topic, "count": self.max_results}
async with aiohttp.ClientSession() as session:
async with session.get(
self.base_url, headers=headers, params=params, timeout=30
) as response:
response.raise_for_status()
data = await response.json()
web_results = data.get("web", {}).get("results", [])
if not web_results:
if __event_emitter__:
await __event_emitter__(
{
"type": "status",
"data": {"description": "No results found", "done": True},
}
)
return f"No web results found for '{topic}'."
output = ""
for i, result in enumerate(web_results[: self.max_results], 1):
title = result.get("title", "No title")
url = result.get("url", "No URL")
description = result.get("description", "No description")
output += f"{i}. {title}\n"
output += f" URL: {url}\n"
output += f" Snippet: {description}\n\n"
if __event_emitter__:
await __event_emitter__(
{
"type": "citation",
"data": {
"document": [description],
"metadata": [{"source": url}],
"source": {"name": title},
},
}
)
if __event_emitter__:
await __event_emitter__(
{
"type": "status",
"data": {"description": "Search completed", "done": True},
}
)
return output
except aiohttp.ClientError as e:
error_msg = f"Brave API error: {str(e)}"
if __event_emitter__:
await __event_emitter__(
{"type": "status", "data": {"description": error_msg, "done": True}}
)
return error_msg
except Exception as e:
error_msg = f"Unexpected error: {str(e)}"
if __event_emitter__:
await __event_emitter__(
{"type": "status", "data": {"description": error_msg, "done": True}}
)
return error_msg