Spaces:
Sleeping
Sleeping
# kids_museum_agent.py | |
from smolagents import ( | |
CodeAgent, | |
DuckDuckGoSearchTool, | |
VisitWebpageTool, | |
HfApiModel, | |
load_tool, | |
tool | |
) | |
import datetime | |
import requests | |
import pytz | |
import yaml | |
import os | |
from tools.final_answer import FinalAnswerTool # Adjust import path if needed | |
######################################## | |
# UTILITY FUNCTION: | |
# Restructure Europeana JSON response | |
######################################## | |
def restructure_europeana_response(europeana_json: dict) -> str: | |
""" | |
Takes a Europeana Search API JSON response and returns a | |
simplified string summary, focusing on child-friendly information. | |
""" | |
# Check if Europe's response is successful | |
if not europeana_json.get("success"): | |
return f"Oops! There was a problem with Europeana: {europeana_json.get('error', 'Unknown error')}" | |
items = europeana_json.get("items", []) | |
if not items: | |
return "Sorry, I couldn’t find anything on Europeana for that topic!" | |
# Build a short list of results | |
result_lines = [] | |
for idx, item in enumerate(items, start=1): | |
# Try to get a title | |
title_list = item.get("title") or [] | |
if not title_list: | |
# fallback: check dcTitleLangAware if "title" is missing | |
dc_title_lang = item.get("dcTitleLangAware", {}) | |
if dc_title_lang: | |
first_lang = next(iter(dc_title_lang)) | |
title_list = dc_title_lang[first_lang] | |
title_str = title_list[0] if title_list else "[No title found]" | |
# Provider (museum/institution) | |
provider_list = item.get("dataProvider") or [] | |
provider_str = provider_list[0] if provider_list else "Unknown provider" | |
# Object type (IMAGE, VIDEO, TEXT, SOUND, etc.) | |
obj_type = item.get("type") or "Unknown type" | |
# A short description | |
desc_list = item.get("dcDescription") or [] | |
desc_str = desc_list[0] if desc_list else "No description available." | |
# Year (if present) | |
year_list = item.get("year") or [] | |
year_str = year_list[0] if year_list else "N/A" | |
# Construct a child-friendly summary | |
# Feel free to reword for an even more "kid-friendly" vibe | |
summary_text = ( | |
f"{idx}) **Title**: {title_str}\n" | |
f" **Where it’s from**: {provider_str}\n" | |
f" **Type of item**: {obj_type}\n" | |
f" **Approx. Year**: {year_str}\n" | |
f" **Fun Fact/Description**: {desc_str}\n" | |
) | |
result_lines.append(summary_text) | |
# Combine the lines into a single string | |
intro = "Here are some cool things I found in Europeana:\n" | |
return intro + "\n".join(result_lines) | |
######################################## | |
# EUROPEANA TOOL | |
######################################## | |
EUROPEANA_API_KEY = "vievinatme" # | |
def query_europeana(query: str) -> str: | |
""" | |
A tool that queries the Europeana Search API for a given query | |
and returns up to 5 results in a kid-friendly summary. | |
Args: | |
query: A string representing the search term (e.g. 'Van Gogh') | |
Returns: | |
A string summary describing up to 5 Europeana items in a child-friendly format. | |
""" | |
endpoint = "https://api.europeana.eu/record/v2/search.json" | |
params = { | |
"query": query, | |
"wskey": EUROPEANA_API_KEY, | |
"rows": 5, | |
} | |
try: | |
response = requests.get(endpoint, params=params) | |
data = response.json() | |
if response.status_code != 200: | |
return f"Oops, something went wrong: {data.get('error', 'Unknown HTTP error')}" | |
return restructure_europeana_response(data) | |
except Exception as e: | |
return f"Error calling Europeana API: {str(e)}" | |
######################################## | |
# TIME 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: | |
tz = pytz.timezone(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)}" | |
######################################## | |
# WIKIPEDIA CULTURAL INFO | |
######################################## | |
def get_cultural_info(topic: str) -> str: | |
""" | |
A tool that retrieves cultural or general info from Wikipedia for a given topic. | |
Args: | |
topic: A string representing the subject to lookup (e.g., 'Renaissance art'). | |
Returns: | |
A short summary text from Wikipedia for the specified topic. | |
""" | |
try: | |
url = ( | |
"https://en.wikipedia.org/w/api.php?" | |
"action=query&prop=extracts&exintro&explaintext&format=json&titles=" + topic | |
) | |
response = requests.get(url) | |
data = response.json() | |
pages = data.get("query", {}).get("pages", {}) | |
if not pages: | |
return f"I couldn't find anything on Wikipedia for '{topic}'." | |
page_id = next(iter(pages)) | |
page_content = pages[page_id] | |
if "missing" in page_content: | |
return f"No page found on Wikipedia for topic: {topic}" | |
extract = page_content.get("extract", "") | |
if not extract: | |
return f"No extract available for '{topic}'." | |
return extract.strip() | |
except Exception as e: | |
return f"Error retrieving cultural info for '{topic}': {str(e)}" | |
######################################## | |
# FINAL ANSWER TOOL (REQUIRED) | |
######################################## | |
final_answer = FinalAnswerTool() | |
######################################## | |
# MODEL | |
######################################## | |
model = HfApiModel( | |
max_tokens=1024, | |
temperature=0.5, | |
model_id='Qwen/Qwen2.5-Coder-32B-Instruct', # or your chosen HF endpoint | |
custom_role_conversions=None | |
) | |
######################################## | |
# OPTIONAL: IMAGE GENERATION TOOL | |
######################################## | |
try: | |
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True) | |
except Exception as e: | |
print("Error loading text-to-image tool:", e) | |
image_generation_tool = None | |
######################################## | |
# PROMPT TEMPLATES (for kids style) | |
######################################## | |
this_dir = os.path.dirname(os.path.abspath(__file__)) | |
prompts_path = os.path.join(this_dir, "prompts.yaml") | |
with open(prompts_path, 'r', encoding='utf-8') as stream: | |
prompt_templates = yaml.safe_load(stream) | |
######################################## | |
# BUILD THE AGENT | |
######################################## | |
tools_list = [ | |
final_answer, | |
DuckDuckGoSearchTool(), | |
VisitWebpageTool(), | |
get_current_time_in_timezone, | |
get_cultural_info, | |
query_europeana, # <--- Our new Europeana tool | |
] | |
if image_generation_tool: | |
tools_list.append(image_generation_tool) | |
agent = CodeAgent( | |
model=model, | |
tools=tools_list, | |
max_steps=6, | |
verbosity_level=1, | |
grammar=None, | |
planning_interval=None, | |
name="KidsMuseumAgent", | |
description="A friendly museum assistant that explains art, history, and culture in kid-friendly language.", | |
prompt_templates=prompt_templates | |
) | |
if __name__ == "__main__": | |
# (OPTIONAL) Launch Gradio Chat UI | |
from Gradio_UI import GradioUI | |
GradioUI(agent).launch() | |