from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool import datetime import requests import pytz import yaml import asyncio import nest_asyncio #import matplotlib from playwright.async_api import async_playwright from PIL import Image import numpy as np import subprocess import json from rapidfuzz import process import gradio as gr from tools.final_answer import FinalAnswerTool from Gradio_UI import GradioUI nest_asyncio.apply() # Ensure async works in a Jupyter/Colab/HF Spaces environment subprocess.run(["apt-get", "update"]) subprocess.run(["apt-get", "install", "-y", "libnss3", "libatk1.0-0", "libatk-bridge2.0-0", "libxcomposite1", "libxdamage1", "libcups2"]) subprocess.run(["playwright", "install", "chromium"]) # 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 ?" def load_image_sources(): with open("expanded.json", "r") as file: # with open("image_sources.json", "r") as file: return json.load(file) image_sources = load_image_sources() def get_image_url(image_type: str, image_sources: dict): """Finds the best match for the given image type in a nested JSON structure.""" choices = list(image_sources.keys()) # Get all available keys # Find the best match using `rapidfuzz` best_match, score, *_ = process.extractOne(image_type, choices, score_cutoff=60) if best_match: # Access the image_sources dictionary directly using the best_match string as the key print(f"Best match found: {best_match}") # Removed category access as it's not needed return image_sources[best_match] # Returns {'url', 'width', 'height', etc.} else: # Default return if no good match is found return { "url": "https://editor.p5js.org/kfahn/full/2XD5Y8MiV", "width": 800, "height": 800 } # def get_image_url(image_type: str): # """Finds the best match for the given image type using fuzzy matching.""" # choices = list(image_sources.keys()) # Get all available keys # best_match, score, *rest = process.extractOne(image_type, choices) # if score > 90: # Set a threshold to ensure a reasonable match # print(best_match) # return image_sources[best_match] # else: # #return None # No good match found # return "https://editor.p5js.org/kfahn/full/2XD5Y8MiV" # async def capture_screenshot(image_type: str): # """Launches Playwright and uses user input, if any, to captures a screenshot of an image from p5.js.""" # print("Launching Playwright...") # async with async_playwright() as p: # browser = await p.chromium.launch(headless=True) # page = await browser.new_page() # #url = "https://openprocessing.org/sketch/2539973" # url = "https://editor.p5js.org/kfahn/full/2XD5Y8MiV" # if image_type: # image_url = get_image_url(image_type) # else: # image_url = url # print(f"Opening image from p5 sketch: {image_url}") # await page.goto(image_url, timeout=120000) # Wait for the image page to load # print("Waiting for image element...") # # await page.wait_for_selector("img", timeout=120000) # Wait for the to be visible # await page.wait_for_timeout(5000) # Allow sketch to fully render # print("Capturing screenshot...") # await page.set_viewport_size({"width": 800, "height": 800}) # await page.locator("iframe").screenshot(path="img.png") # await browser.close() # print("Screenshot saved!") async def capture_screenshot(image_type: str): """Captures a screenshot of an image from p5.js.""" print("Launching Playwright...") async with async_playwright() as p: browser = await p.chromium.launch(headless=True) page = await browser.new_page() # Load image sources from JSON image_sources = load_image_sources() image_data = get_image_url(image_type, image_sources) image_url = image_data["url"] width = image_data["width"] height = image_data["height"] print(f"Opening image: {image_url}") await page.goto(image_url, timeout=120000) # Load page print("Waiting for render...") await page.wait_for_timeout(5000) print(f"Setting viewport to {width}x{height}...") await page.set_viewport_size({"width": width, "height": height}) print("Capturing screenshot...") await page.locator("iframe").screenshot(path="img.png") await browser.close() print("Screenshot saved!") @tool def grab_image(image_type: str) -> Image: """ Fetches an user specified image or generative object from a p5.js sketch. This tool can be used to show a user what the generative art looks like. This function sends uses Playwright to launch a headless server and grab a screenshot of a p5.js sketch. Args: image_type: The art type or generative object. Returns: image: The screen shot of the p5.js sketch as an image. """ print("Running async Playwright screenshot...") loop = asyncio.new_event_loop() # Create a new event loop (Fixes issues on HF Spaces) asyncio.set_event_loop(loop) loop.run_until_complete(capture_screenshot(image_type)) print("Loading image for Gradio...") img = Image.open("img.png") return img @tool def get_joke() -> str: """ Fetches a random joke from the JokeAPI. This function sends a GET request to the JokeAPI to retrieve a random joke. It handles both single jokes and two-part jokes (setup and delivery). If the request fails or the response does not contain a joke, an error message is returned. Returns: str: The joke as a string, or an error message if the joke could not be fetched. """ url = "https://v2.jokeapi.dev/joke/Any?type=single" try: response = requests.get(url) response.raise_for_status() data = response.json() if "joke" in data: return data["joke"] elif "setup" in data and "delivery" in data: return f"{data['setup']} - {data['delivery']}" else: return "Error: Unable to fetch joke." except requests.exceptions.RequestException as e: return f"Error fetching joke: {str(e)}" #https://github.com/huggingface/smolagents/blob/main/examples/multiple_tools.py @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)}" 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 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=[final_answer, get_joke, grab_image], ## 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()