alexgoncharov's picture
Update app.py
f044bad verified
from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
import datetime
import requests
import pytz
import yaml
from tools.final_answer import FinalAnswerTool
from Gradio_UI import GradioUI
# Below is an example of a tool that does nothing. Amaze us with your creativity !
@tool
def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
#Keep this format for the description / args / args description but feel free to modify the tool
"""A tool that does nothing yet
Args:
arg1: the first argument
arg2: the second argument
"""
return "What magic will you build ?"
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""A tool that fetches the current local time in a specified timezone.
Args:
timezone: A string representing a valid timezone (e.g., 'America/New_York').
"""
try:
# Create timezone object
tz = pytz.timezone(timezone)
# Get current time in that timezone
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return f"The current local time in {timezone} is: {local_time}"
except Exception as e:
return f"Error fetching time for timezone '{timezone}': {str(e)}"
@tool
def execute_python_code(code: str, timeout: int = 10) -> str:
"""Executes Python code and returns the output.
Args:
code: The Python code to execute as a string
timeout: Maximum execution time in seconds (default: 10)
"""
import sys
import io
from contextlib import redirect_stdout, redirect_stderr
import traceback
import signal
# Create string buffers for capturing output
stdout_buffer = io.StringIO()
stderr_buffer = io.StringIO()
# Set up timeout handler
def timeout_handler(signum, frame):
raise TimeoutError(f"Code execution timed out after {timeout} seconds")
# Store original handler to restore later
original_handler = signal.signal(signal.SIGALRM, timeout_handler)
result = None
try:
# Set alarm
signal.alarm(timeout)
# Create a restricted globals dictionary
restricted_globals = {
"__builtins__": {
name: __builtins__[name] for name in [
"abs", "all", "any", "bool", "chr", "dict", "dir", "divmod",
"enumerate", "filter", "float", "format", "frozenset", "hash",
"hex", "int", "isinstance", "issubclass", "len", "list", "map",
"max", "min", "oct", "ord", "pow", "print", "range", "repr",
"reversed", "round", "set", "slice", "sorted", "str", "sum",
"tuple", "type", "zip"
]
}
}
# Add some safe modules
import math
import random
import datetime
import json
import re
restricted_globals["math"] = math
restricted_globals["random"] = random
restricted_globals["datetime"] = datetime
restricted_globals["json"] = json
restricted_globals["re"] = re
# Execute the code with redirected output
with redirect_stdout(stdout_buffer), redirect_stderr(stderr_buffer):
# Execute code in a restricted environment
exec_globals = {}
exec(code, restricted_globals, exec_globals)
# Check for a return value if the last statement is an expression
lines = code.strip().split('\n')
if lines and not (lines[-1].strip().startswith(('def ', 'class ', 'if ', 'for ', 'while ', 'try:', 'with '))) and \
not any(op in lines[-1] for op in ['=', '+=', '-=', '*=', '/=', '%=']):
try:
result = eval(lines[-1], restricted_globals, exec_globals)
except:
pass
# Cancel the alarm
signal.alarm(0)
# Collect output
stdout_output = stdout_buffer.getvalue()
stderr_output = stderr_buffer.getvalue()
# Format the response
response = ""
if stdout_output:
response += f"Standard Output:\n{stdout_output}\n"
if stderr_output:
response += f"Standard Error:\n{stderr_output}\n"
if result is not None:
response += f"Result: {result}\n"
return response.strip() or "Code executed successfully with no output."
except TimeoutError as e:
return f"Error: {str(e)}"
except Exception as e:
# Get full traceback
err_traceback = traceback.format_exc()
return f"Error executing code:\n{err_traceback}"
finally:
# Reset the alarm and restore original handler
signal.alarm(0)
signal.signal(signal.SIGALRM, original_handler)
final_answer = FinalAnswerTool()
# If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
model = HfApiModel(
max_tokens=2096,
temperature=0.5,
# model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud',
custom_role_conversions=None,
)
# Import tool from Hub
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
with open("prompts.yaml", 'r') as stream:
prompt_templates = yaml.safe_load(stream)
agent = CodeAgent(
model=model,
tools=[get_current_time_in_timezone, final_answer, execute_python_code], ## add your tools here (don't remove final answer)
max_steps=6,
verbosity_level=1,
grammar=None,
planning_interval=None,
name=None,
description=None,
prompt_templates=prompt_templates
)
GradioUI(agent).launch()