AmmarFahmy
adding all files
105b369
import json
from os import getenv
from typing import Optional
from phi.tools import Toolkit
from phi.utils.log import logger
try:
from exa_py import Exa
except ImportError:
raise ImportError("`exa_py` not installed. Please install using `pip install exa_py`")
class ExaTools(Toolkit):
def __init__(
self,
api_key: Optional[str] = None,
search: bool = False,
search_with_contents: bool = True,
show_results: bool = False,
):
super().__init__(name="exa")
self.api_key = api_key or getenv("EXA_API_KEY")
if not self.api_key:
logger.error("EXA_API_KEY not set. Please set the EXA_API_KEY environment variable.")
self.show_results = show_results
if search:
self.register(self.search_exa)
if search_with_contents:
self.register(self.search_exa_with_contents)
def search_exa(self, query: str, num_results: int = 5) -> str:
"""Searches Exa for a query.
:param query: The query to search for.
:param num_results: The number of results to return.
:return: Links of relevant documents from exa.
"""
if not self.api_key:
return "Please set the EXA_API_KEY"
try:
exa = Exa(self.api_key)
logger.debug(f"Searching exa for: {query}")
exa_results = exa.search(query, num_results=num_results)
exa_search_urls = [result.url for result in exa_results.results]
parsed_results = "\n".join(exa_search_urls)
if self.show_results:
logger.info(parsed_results)
return parsed_results
except Exception as e:
logger.error(f"Failed to search exa {e}")
return f"Error: {e}"
def search_exa_with_contents(self, query: str, num_results: int = 3, text_length_limit: int = 1000) -> str:
"""Searches Exa for a query and returns the contents from the search results.
:param query: The query to search for.
:param num_results: The number of results to return. Defaults to 3.
:param text_length_limit: The length of the text to return. Defaults to 1000.
:return: JSON string of the search results.
"""
if not self.api_key:
return "Please set the EXA_API_KEY"
try:
exa = Exa(self.api_key)
logger.debug(f"Searching exa for: {query}")
exa_results = exa.search_and_contents(query, num_results=num_results)
exa_results_parsed = []
for result in exa_results.results:
result_dict = {"url": result.url}
if result.text:
result_dict["text"] = result.text[:text_length_limit]
if result.author:
result_dict["author"] = result.author
if result.title:
result_dict["title"] = result.title
exa_results_parsed.append(result_dict)
parsed_results = json.dumps(exa_results_parsed, indent=2)
if self.show_results:
logger.info(parsed_results)
return parsed_results
except Exception as e:
logger.error(f"Failed to search exa {e}")
return f"Error: {e}"