File size: 6,967 Bytes
3469f37 d3b823a 3469f37 d3b823a 3469f37 d3b823a 3469f37 d3b823a 3469f37 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
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))
|