Spaces:
Sleeping
Sleeping
from smolagents import DuckDuckGoSearchTool, GoogleSearchTool | |
from youtube_transcript_api import YouTubeTranscriptApi | |
import wikipedia | |
from wikipedia_tables_parser import fetch_wikipedia_tables | |
import pandas as pd | |
from typing import Any | |
import os | |
from dotenv import load_dotenv | |
load_dotenv() | |
import importlib.util | |
import sys | |
import io | |
import contextlib | |
from llama_index.llms.openrouter import OpenRouter | |
from llama_index.core.types import ChatMessage | |
llm = OpenRouter( | |
api_key=os.getenv("OPENROUTER_API_KEY"), | |
model="google/gemini-2.5-flash-preview", | |
temperature=0.7, | |
) | |
def reverse_text(text: str, **kwargs) -> str: | |
""" | |
Returns the reversed version of the text. | |
If you receive some unknown text, that can't be recognized and analyzed, then you need to use this tool to make it clear. | |
Args: | |
text: text to be reversed | |
Return: | |
The reversed text. | |
""" | |
try: | |
print(text[::-1]) | |
return text[::-1] | |
except Exception as e: | |
raise ValueError(f"Can't reverse text: {e}") | |
def fetch_historical_event_data(event_name: str, year: str, **kwargs) -> str: | |
""" | |
Fetches data about historical event that occured in certain year. | |
Some examples of events: Olympics games, Footbal games, NBA etc. | |
Args: | |
event_name: String name of the event | |
year: String year of the event | |
Return: | |
String with data about the event | |
""" | |
result = wikipedia.page(f"{event_name} in {year}") | |
url = result.url | |
content = result.content | |
try: | |
tables = pd.read_html(url) | |
except Exception as e: | |
tables = fetch_wikipedia_tables(url) | |
result = f"Content: {content}\nTables: {tables}" | |
return result | |
def classify_fruit_vegitable(item: str, **kwargs) -> str: | |
""" | |
Classifies items to fruits and vegitables | |
Args: | |
item: Item to classify | |
Returns: | |
Text with explanation whether it is a fruit or vegetable. | |
""" | |
response = llm.chat( | |
messages=[ | |
ChatMessage( | |
content=f"Classify whether it is fruit or vegetable: {item}. Return only `fruit` or `vegetable` without explanations" | |
) | |
] | |
) | |
return response.message.content | |
def web_search(query: str, **kwargs) -> str: | |
""" | |
Returns web search results for the provided query. | |
Don't use it for Wikipedia queries. For Wikipedia queries use wikipedia_search tool. | |
Important, query is human-language string input, not the URL or key. | |
Args: | |
query: query to search in WEB | |
Return: | |
String with web search results. | |
""" | |
# result = DuckDuckGoSearchTool().forward(query) | |
result = GoogleSearchTool(provider="serpapi").forward(query) | |
print(result) | |
return result | |
def wikipedia_search(query: str, **kwargs) -> Any: | |
""" | |
Returns wikipedia search results for the provided query. | |
Args: | |
query: query to search in WIKIPEDIA | |
Return: | |
Wikipedia search results. | |
""" | |
result = wikipedia.page(query) | |
url = result.url | |
content = result.content | |
try: | |
tables = pd.read_html(url) | |
except: | |
tables = fetch_wikipedia_tables(url) | |
result = f"Content: {content}\nTables: {tables}" | |
return result | |
def multiply(a: float, b: float, **kwargs) -> float: | |
""" | |
Multiply two numbers. | |
Args: | |
a: First number | |
b: Second number | |
Return: | |
The product of the two numbers. | |
""" | |
return a * b | |
def length(iterable: Any, **kwargs) -> int: | |
""" | |
Return the length of an iterable. | |
Args: | |
iterable: Any iterable | |
Return: | |
The length of the iterable. | |
""" | |
return len(iterable) | |
def execute_python_file(file_path: str) -> Any: | |
""" | |
Executes a Python file and returns its result. | |
This function takes a path to a Python file, executes it by importing it as a module, | |
and returns the result. The file should contain a function call that produces | |
the result to be returned. | |
Args: | |
file_path (str): Path to the Python file to execute. | |
Returns: | |
Any: The result of executing the Python file. If the file sets a variable | |
named 'result', that value will be returned. | |
Raises: | |
FileNotFoundError: If the specified file does not exist. | |
ImportError: If there was an error importing the Python file. | |
Example: | |
>>> # If example.py contains: result = 2 + 3 | |
>>> execute_python_file('example.py') | |
5 | |
""" | |
# Verify file exists | |
if not os.path.isfile(file_path): | |
raise FileNotFoundError(f"File not found: {file_path}") | |
# Get the directory and filename | |
file_dir = os.path.dirname(os.path.abspath(file_path)) | |
file_name = os.path.basename(file_path) | |
module_name = file_name.replace(".py", "") | |
# Store original sys.path and add the file's directory | |
original_sys_path = sys.path.copy() | |
sys.path.insert(0, file_dir) | |
# Prepare stdout/stderr capture | |
stdout_capture = io.StringIO() | |
stderr_capture = io.StringIO() | |
# Store the original __main__ module | |
original_main = sys.modules.get("__main__") | |
try: | |
spec = importlib.util.spec_from_file_location(module_name, file_path) | |
if spec is None or spec.loader is None: | |
raise ImportError(f"Could not load module spec from {file_path}") | |
module = importlib.util.module_from_spec(spec) | |
sys.modules[module_name] = module | |
# Execute the module | |
with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr( | |
stderr_capture | |
): | |
spec.loader.exec_module(module) | |
if hasattr(module, "result"): | |
return module.result | |
else: | |
print(f"RESULT PYTHON: {stdout_capture.getvalue().strip()}") | |
return stdout_capture.getvalue().strip() | |
except Exception as e: | |
error_output = stderr_capture.getvalue() | |
if error_output: | |
raise type(e)(f"{str(e)}\nProgram output: {error_output}") from None | |
else: | |
raise | |
finally: | |
sys.path = original_sys_path | |
if module_name in sys.modules: | |
del sys.modules[module_name] | |
def trascript_youtube(video_id: str, **kwargs) -> list: | |
""" | |
Returns transcript of YouTube video. | |
Args: | |
video_id: ID of youtube video (Pass in the video ID, NOT the video URL. For a video with the URL https://www.youtube.com/watch?v=12345 the ID is 12345.) | |
Return: | |
Transcript of YouTube video. | |
""" | |
ytt_api = YouTubeTranscriptApi() | |
result = ytt_api.fetch(video_id) | |
return result.snippets | |
def read_excel(path: str, **kwargs) -> pd.DataFrame: | |
""" | |
Reads xlsx file | |
Args: | |
path: path to xlsx file | |
Return: | |
Pandas dataframe | |
""" | |
return pd.read_excel(path) | |
def pandas_column_sum( | |
pandas_column_values: list[int | float], column_name: str, **kwargs | |
) -> float: | |
""" | |
Computes sum on pandas dataframe column | |
Args: | |
pandas_column_values: List with float or integer pandas values | |
column_name: Name of the column | |
Return: | |
Sum of the column | |
""" | |
return sum(pandas_column_values) | |
def final_answer(query: str, answer: str, **kwargs) -> str: | |
""" | |
Prepare the final answer for the user. It should be always used as a last step. | |
Args: | |
query: The initial query of the user | |
answer: The answer to format and return to the user | |
Return: | |
The final answer. | |
""" | |
return f""" | |
User query: {query} | |
Final answer from agent: {answer} | |
Adapt final answer to user request. | |
Final answer should be a number or as few words as possible or a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string. | |
There might be requested exact number, then you need to compress the output so that it was only number without any comments or explanations (float or integer). | |
And on the other hand, the question might request some exact string value. Don't explain it, just return this value (For example, insted of `In response to the question, desired person is X` return only `X`) | |
""" | |
# print(wikipedia_search("Mercedes Sosa studio albums")) | |
# execute_python_file("f918266a-b3e0-4914-865d-4faa564f1aef.py") | |