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() | |