|
import os |
|
from typing import Union |
|
import requests |
|
import pandas as pd |
|
import subprocess |
|
import sys |
|
from smolagents import tool |
|
|
|
|
|
@tool |
|
def reverse_string(text: str) -> str: |
|
""" |
|
Reverse the order of characters in a given string. |
|
|
|
Args: |
|
text (str): The input string to be reversed. |
|
|
|
Returns: |
|
str: A new string with characters in reverse order. |
|
|
|
Example: |
|
>>> reverse_string("hello") |
|
'olleh' |
|
>>> reverse_string("Python") |
|
'nohtyP' |
|
""" |
|
return text[::-1] |
|
|
|
|
|
def download_file(url: str, filename: str) -> str: |
|
""" |
|
Download a file from the given URL and save it to a temporary location. |
|
|
|
Args: |
|
url (str): The URL of the file to download. |
|
filename (str): The name to use for the saved file. |
|
|
|
Returns: |
|
str: Full path to the downloaded file in temporary directory. |
|
|
|
Raises: |
|
requests.RequestException: If the download fails. |
|
|
|
Example: |
|
>>> path = download_file("https://example.com/data.json", "my_data.json") |
|
>>> print(path) |
|
'/tmp/tmpxyz123/my_data.json' |
|
""" |
|
|
|
file_path = os.path.join("downloaded_files", filename) |
|
if not os.path.exists(file_path): |
|
print(f"Attempting to download file from: {url}") |
|
try: |
|
response = requests.get(url, timeout=30) |
|
response.raise_for_status() |
|
os.makedirs("downloaded_files", exist_ok=True) |
|
with open(file_path, "wb") as f: |
|
f.write(response.content) |
|
except requests.exceptions.RequestException as e: |
|
print(f"Error downloading file: {e}") |
|
return file_path |
|
|
|
@tool |
|
def process_excel_file(file_path: str) -> pd.DataFrame: |
|
""" |
|
Process an Excel file and return its data as Pandas DataFrame. |
|
Args: |
|
file_path (str): Path to the Excel file (.xlsx or .xls). |
|
|
|
Returns: |
|
pd.DataFrame: processed DataFrame. |
|
|
|
Example: |
|
>>> result = process_excel_file( |
|
... "data.xlsx", |
|
... ) |
|
>>> print(result.head()) |
|
""" |
|
return pd.read_excel(file_path) |
|
|
|
|
|
@tool |
|
def is_text_file(file_path: str) -> bool: |
|
"""Check if a file is a text file by attempting to decode it as UTF-8. |
|
|
|
Args: |
|
file_path (str): Path to the file to check. |
|
|
|
Returns: |
|
bool: True if the file is likely a text file, False if it is likely binary |
|
or an error occurs. |
|
|
|
Raises: |
|
None: All exceptions are caught and handled internally. |
|
|
|
Example: |
|
>>> is_text_file("example.txt") |
|
True |
|
>>> is_text_file("image.png") |
|
False |
|
""" |
|
try: |
|
with open(file_path, 'rb') as file: |
|
|
|
chunk: bytes = file.read(1024) |
|
|
|
chunk.decode('utf-8') |
|
return True |
|
except UnicodeDecodeError: |
|
return False |
|
except Exception as e: |
|
print(f"Error reading file: {e}") |
|
return False |
|
|
|
|
|
@tool |
|
def execute_python_file(file_path: str) -> str: |
|
""" |
|
Execute a Python code from file_path in a separate process and return its output as a numeric value. |
|
|
|
This function runs the specified Python file using the Python interpreter |
|
in a separate subprocess with error handling and a 60-second timeout. |
|
|
|
Args: |
|
file_path (str): Path to the Python file to execute. |
|
|
|
Returns: |
|
str: The output from the executed script, or an error message if execution failed. |
|
|
|
Raises: |
|
None: All exceptions are handled internally and returned as error strings. |
|
|
|
Examples: |
|
>>> output = execute_python_file("script.py") |
|
>>> print(output) |
|
"Hello, World!" |
|
|
|
>>> output = execute_python_file("nonexistent.py") |
|
>>> print(output) |
|
"Error: File not found: nonexistent.py" |
|
""" |
|
|
|
if not os.path.exists(file_path): |
|
return f"Error: File not found: {file_path}" |
|
|
|
|
|
if not file_path.endswith('.py'): |
|
return f"Error: File is not a Python file: {file_path}" |
|
|
|
try: |
|
|
|
result = subprocess.run( |
|
[sys.executable, file_path], |
|
capture_output=True, |
|
text=True, |
|
timeout=180 |
|
) |
|
|
|
|
|
if result.stderr and result.returncode != 0: |
|
return f"Error: {result.stderr.strip()}" |
|
elif result.stderr: |
|
|
|
return f"{result.stdout.strip()}\nWarnings/Info: {result.stderr.strip()}" |
|
else: |
|
for i in result.stdout.strip().split(): |
|
try: |
|
return str(int(i.strip())) |
|
except: |
|
pass |
|
return result.stdout.strip() if result.stdout.strip() else "Script executed successfully with no output" |
|
|
|
except subprocess.TimeoutExpired: |
|
return "Error: Execution timed out after 60 seconds" |
|
|
|
except subprocess.SubprocessError as e: |
|
return f"Error: Subprocess error: {str(e)}" |
|
|
|
except Exception as e: |
|
return f"Error: Unexpected error: {str(e)}" |
|
|
|
@tool |
|
def get_ingredients(item: str) -> str: |
|
""" |
|
Extract known ingredients from a given text string. |
|
|
|
This function identifies and extracts recognized ingredients (fruits, vegetables, |
|
and common cooking products) from the input text and returns them as a |
|
comma-separated string. |
|
|
|
Args: |
|
item (str): Input text containing potential ingredient names separated by spaces. |
|
|
|
Returns: |
|
str: Comma-separated string of recognized ingredients in alphabetical order. |
|
Returns empty string if no recognized ingredients are found. |
|
|
|
Examples: |
|
>>> get_ingredients("apple banana flour") |
|
"apple,banana,flour" |
|
|
|
>>> get_ingredients("I need tomato and onion for cooking") |
|
"onion,tomato" |
|
|
|
>>> get_ingredients("car house table") |
|
"" |
|
|
|
>>> get_ingredients("APPLE Carrot SUGAR") |
|
"apple,carrot,sugar" |
|
""" |
|
|
|
fruits = { |
|
'apple', 'banana', 'orange', 'strawberry', 'blueberry', 'raspberry', |
|
'mango', 'pineapple', 'grape', 'kiwi', 'peach', 'pear', 'plum', |
|
'cherry', 'lemon', 'lime', 'avocado', 'pomegranate', 'fig', 'date' |
|
} |
|
|
|
vegetables = { |
|
'carrot', 'broccoli', 'spinach', 'tomato', 'cucumber', 'lettuce', |
|
'onion', 'garlic', 'potato', 'sweet potato', 'zucchini', 'pepper', |
|
'eggplant', 'cauliflower', 'cabbage', 'kale', 'mushroom', 'celery' |
|
} |
|
|
|
products = { |
|
'vanilla', 'sugar', 'flour', 'salt', 'pepper', 'oil', 'butter', |
|
'milk', 'cream', 'cheese', 'yogurt', 'egg', 'honey', 'vinegar', |
|
'baking powder', 'baking soda', 'yeast', 'cinnamon', 'cocoa' |
|
} |
|
|
|
def is_ingredient(ingredient: str) -> bool: |
|
return ingredient in fruits or ingredient in vegetables or ingredient in products |
|
|
|
items = set([x.lower().strip() for x in item.split() if is_ingredient(x)]) |
|
return ','.join(sorted(items)) |
|
|