Spaces:
Sleeping
Sleeping
File size: 5,947 Bytes
9b5b26a c19d193 6aae614 0ca4cfd 8fe992b 9b5b26a 5df72d6 9b5b26a b8fe276 9b5b26a b8fe276 9b5b26a b8fe276 9b5b26a 0ca4cfd ef3b735 0ca4cfd ef3b735 0ca4cfd 9b5b26a 8c01ffb 6aae614 ae7a494 e121372 bf6d34c 29ec968 fe328e0 13d500a 8c01ffb 9b5b26a 8c01ffb 861422e 9b5b26a 8c01ffb 8fe992b 459594c 8c01ffb 861422e 8fe992b 9b5b26a 8c01ffb |
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 |
from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
import datetime
import requests
import pytz
import yaml
from tools.final_answer import FinalAnswerTool
from urllib.parse import quote
from Gradio_UI import GradioUI
# Below is an example of a tool that does nothing. Amaze us with your creativity !
@tool
def get_chinese_zodiac_sign(year: int = None) -> str:
"""
A tool that translates a Gregorian year into its corresponding Chinese Zodiac animal sign.
The Chinese Zodiac cycle is based on a 12-year cycle, with each year
assigned to an animal. The cycle starts with the Rat.
Args:
year (int): The Gregorian calendar year (e.g., 1997, 2025).
Returns:
str: The name of the Chinese Zodiac animal sign.
"""
# 1. List of 12 animals in order, starting with Rat
zodiac_signs = [
"Rat", "Ox", "Tiger", "Rabbit", "Dragon", "Snake",
"Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig"
]
# 2. Calculate the index: 1900 was the year of the Rat (index 0).
# The modulo 12 operation ensures the index wraps around correctly.
index = (year - 1900) % 12
# 3. Return the animal sign at the calculated index
return zodiac_signs[index]
@tool
def get_a_joke(keyword: str = None) -> str:
"""
A tool that fetches a joke.
It can return either a single-part or a two-part joke.
The joke can be optionally filtered by a keyword to provide some relevance.
If no keyword is provided, a random joke from the "Any" category is returned.
Args:
keyword: An optional keyword to search for within the joke text.
Returns:
A string containing the joke, or an error message if the fetch fails.
"""
base_url = "https://v2.jokeapi.dev/joke/Any"
# Removed 'type': 'single' to allow for both single and two-part jokes.
# We still enforce safe-mode for safety.
params = {
'safe-mode': ''
}
if keyword:
# URL-encode the keyword to handle spaces and special characters
safe_keyword = quote(keyword)
# The API uses the 'contains' parameter for keyword filtering
params['contains'] = safe_keyword
# We implement a simple retry mechanism with exponential backoff for robustness
max_retries = 3
for attempt in range(max_retries):
try:
# Make the API request
response = requests.get(base_url, params=params, timeout=10)
# Raise an exception for bad status codes (4xx or 5xx)
response.raise_for_status()
data = response.json()
# The JokeAPI returns a 'success' field implicitly, but checks for 'error'
if data.get('error') is True:
# If the API returns an error, it often means no joke was found for the keyword
return (f"**[Joke Tool Error]** Sorry, I couldn't find a joke about '{keyword}'! "
f"Perhaps try a more general term. (API Message: {data.get('message', 'Unknown error')})")
# --- Logic to handle both single and two-part jokes ---
if data.get('type') == 'single':
# Case 1: Single-part joke
return data.get('joke')
elif data.get('type') == 'twopart':
# Case 2: Two-part joke (combine setup and delivery)
setup = data.get('setup', 'Setup missing...')
delivery = data.get('delivery', 'Punchline missing...')
return f"{setup}\n\n...{delivery}"
else:
return "The Joke API returned an unknown joke format."
except requests.exceptions.RequestException as e:
# Handle connection errors, timeouts, and bad status codes
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < max_retries - 1:
# Wait before retrying (exponential backoff)
wait_time = 2 ** attempt
time.sleep(wait_time)
else:
return f"**[Joke Tool Error]** Failed to connect to the Joke API after {max_retries} attempts."
except Exception as e:
return f"**[Joke Tool Error]** An unexpected error occurred: {e}"
@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_chinese_zodiac_sign, get_a_joke, get_current_time_in_timezone, image_generation_tool], ## 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() |