File size: 7,593 Bytes
a9ded72
 
 
 
 
 
 
 
 
 
9b5b26a
 
 
c19d193
a9ded72
6943645
7a40ff8
9b5b26a
a9ded72
7a40ff8
 
a9ded72
7a40ff8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bdb86e
7a40ff8
 
 
 
 
 
4bdb86e
 
 
 
 
 
7a40ff8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6943645
7a40ff8
 
 
 
 
 
9b5b26a
 
a9ded72
 
9b5b26a
 
 
 
 
 
 
 
 
8c01ffb
a9ded72
7a40ff8
 
 
66bf097
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a9ded72
66bf097
 
7a40ff8
66bf097
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c01ffb
a9ded72
 
 
6aae614
a9ded72
 
7a40ff8
a9ded72
e121372
a9ded72
 
7a40ff8
a9ded72
13d500a
8c01ffb
a9ded72
7a40ff8
a9ded72
 
 
 
 
 
 
 
7a40ff8
a9ded72
 
 
 
 
8c01ffb
a9ded72
 
 
 
7a40ff8
a9ded72
 
 
7a40ff8
 
a9ded72
 
 
 
 
8c01ffb
8fe992b
a9ded72
8c01ffb
 
 
 
a9ded72
 
861422e
8fe992b
 
a9ded72
7a40ff8
a9ded72
 
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# 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"  #

@tool
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
########################################
@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
########################################
@tool
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()