h2oaimichalmarszalek's picture
redesign
d3b823a
raw
history blame
6.97 kB
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:
# Read a small chunk of the file (1024 bytes)
chunk: bytes = file.read(1024)
# Try decoding as UTF-8 text
chunk.decode('utf-8')
return True # No decoding errors, likely a text file
except UnicodeDecodeError:
return False # Decoding failed, likely a binary file
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"
"""
# Check if file exists
if not os.path.exists(file_path):
return f"Error: File not found: {file_path}"
# Check if file is actually a Python file
if not file_path.endswith('.py'):
return f"Error: File is not a Python file: {file_path}"
try:
# Execute the Python file in a separate process
result = subprocess.run(
[sys.executable, file_path],
capture_output=True,
text=True,
timeout=180 # 180 seconds timeout
)
# If there's stderr output, include it in the result
if result.stderr and result.returncode != 0:
return f"Error: {result.stderr.strip()}"
elif result.stderr:
# Include stderr even if return code is 0 (warnings, etc.)
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"
"""
# Lists of common fruits, vegetables, and products
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))