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))