giuliotraversaal commited on
Commit
8f69d14
·
verified ·
1 Parent(s): 2d8b04e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +222 -0
app.py ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import os
3
+ import random
4
+ import requests
5
+ import streamlit as st
6
+ from io import BytesIO
7
+ from PIL import Image
8
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, Tool
9
+ from huggingface_hub import login
10
+ import warnings
11
+
12
+ warnings.filterwarnings("ignore")
13
+
14
+ # Set page configuration
15
+ st.set_page_config(
16
+ page_title="SmolaAgents Tools",
17
+ page_icon="🤖",
18
+ layout="wide",
19
+ initial_sidebar_state="expanded"
20
+ )
21
+
22
+ # Initialize HF API key from environment variable
23
+ @st.cache_resource
24
+ def initialize_api():
25
+ hf_token = os.environ.get("HF_TOKEN")
26
+ if hf_token:
27
+ login(hf_token)
28
+ else:
29
+ st.warning("Warning: HF_API_TOKEN not found in environment variables")
30
+
31
+ # Initialize the model
32
+ return HfApiModel(model_id="meta-llama/Llama-3.3-70B-Instruct")
33
+
34
+ model = initialize_api()
35
+
36
+ # Define all your tools
37
+ class RandomComicFetcher(Tool):
38
+ name = "fetch_random_comic_image"
39
+ description = "Fetches the image of a random XKCD comic"
40
+ inputs = {}
41
+ output_type = "string"
42
+
43
+ def __init__(self):
44
+ super().__init__()
45
+ self.xkcd_base_url = "https://xkcd.com/"
46
+ self.xkcd_latest_url = f"{self.xkcd_base_url}info.0.json"
47
+
48
+ def forward(self):
49
+ try:
50
+ # Fetch the latest comic info to get max comic number
51
+ latest_resp = requests.get(self.xkcd_latest_url)
52
+ latest_resp.raise_for_status()
53
+ latest_data = latest_resp.json()
54
+ max_comic_id = latest_data["num"]
55
+
56
+ # Pick a random comic ID between 1 and latest
57
+ selected_id = random.randint(1, max_comic_id)
58
+ comic_info_url = f"{self.xkcd_base_url}{selected_id}/info.0.json"
59
+
60
+ # Fetch comic metadata
61
+ comic_resp = requests.get(comic_info_url)
62
+ comic_resp.raise_for_status()
63
+ comic_data = comic_resp.json()
64
+ comic_img_url = comic_data["img"]
65
+ comic_title = comic_data["title"]
66
+ comic_alt = comic_data["alt"]
67
+
68
+ # Download and return the comic image
69
+ image_resp = requests.get(comic_img_url)
70
+ image_resp.raise_for_status()
71
+ img = Image.open(BytesIO(image_resp.content))
72
+
73
+ return img, comic_title, comic_alt, comic_img_url
74
+ except requests.exceptions.RequestException as err:
75
+ st.error(f"Could not fetch comic: {err}")
76
+ return None, "Error fetching comic", "Error details", ""
77
+
78
+ class PrimeCheckTool(Tool):
79
+ name = "prime_check"
80
+ description = "Checks if a given number is a prime number."
81
+ inputs = {
82
+ "number": {
83
+ "type": "integer",
84
+ "description": "The number to check for primality.",
85
+ }
86
+ }
87
+ output_type = "boolean"
88
+
89
+ def forward(self, number: int) -> bool:
90
+ if number < 2:
91
+ return False
92
+ for i in range(2, int(number**0.5) + 1):
93
+ if number % i == 0:
94
+ return False
95
+ return True
96
+
97
+ # Initialize tools
98
+ search_tool = DuckDuckGoSearchTool()
99
+ random_comic = RandomComicFetcher()
100
+ prime_check_tool = PrimeCheckTool()
101
+
102
+ # Streamlit App
103
+ st.title("SmolaAgents Tools")
104
+ st.markdown("Select a tool from the sidebar and interact with AI-powered assistants")
105
+
106
+ # Sidebar for tool selection
107
+ with st.sidebar:
108
+ st.title("Tool Selection")
109
+ tool_choice = st.radio(
110
+ "Choose a tool:",
111
+ ["Search Tool", "XKCD Comic Fetcher", "Prime Number Checker"]
112
+ )
113
+
114
+ st.divider()
115
+ st.markdown("### About")
116
+ st.markdown("""
117
+ This app demonstrates the capabilities of SmolaAgents, allowing you to:
118
+ - Search the web with an AI assistant
119
+ - Fetch random XKCD comics with AI commentary
120
+ - Check if numbers are prime with creative explanations
121
+ """)
122
+
123
+ # Main content area
124
+ if tool_choice == "Search Tool":
125
+ st.header("AI Web Search")
126
+ st.markdown("Ask any question and the AI will search the web for answers")
127
+
128
+ query = st.text_input("Enter your search query:", placeholder="What are the latest advancements in renewable energy?")
129
+
130
+ if st.button("Search"):
131
+ if query:
132
+ with st.spinner("Searching and processing..."):
133
+ agent = CodeAgent(tools=[search_tool], model=model)
134
+ response = agent.run(query)
135
+ st.success("Search complete!")
136
+ st.markdown("### Results")
137
+ st.markdown(response)
138
+ else:
139
+ st.warning("Please enter a search query")
140
+
141
+ elif tool_choice == "XKCD Comic Fetcher":
142
+ st.header("XKCD Comic Explorer")
143
+ st.markdown("Fetch a random XKCD comic and get AI commentary")
144
+
145
+ if "comic_fetched" not in st.session_state:
146
+ st.session_state.comic_fetched = False
147
+ st.session_state.comic_img = None
148
+ st.session_state.comic_title = ""
149
+ st.session_state.comic_alt = ""
150
+ st.session_state.comic_url = ""
151
+
152
+ col1, col2 = st.columns([1, 2])
153
+
154
+ with col1:
155
+ if st.button("Fetch Random Comic"):
156
+ with st.spinner("Fetching a random comic..."):
157
+ img, title, alt, url = random_comic.forward()
158
+ if img:
159
+ st.session_state.comic_fetched = True
160
+ st.session_state.comic_img = img
161
+ st.session_state.comic_title = title
162
+ st.session_state.comic_alt = alt
163
+ st.session_state.comic_url = url
164
+ st.experimental_rerun()
165
+
166
+ if st.session_state.comic_fetched:
167
+ with col1:
168
+ st.image(st.session_state.comic_img, caption=st.session_state.comic_title)
169
+ st.caption(f"Alt text: {st.session_state.comic_alt}")
170
+ st.markdown(f"[View on XKCD]({st.session_state.comic_url})")
171
+
172
+ with col2:
173
+ st.subheader("Ask AI about this comic")
174
+ query = st.text_input("What would you like to know about this comic?",
175
+ placeholder="Explain this comic in a funny way")
176
+
177
+ if st.button("Ask AI"):
178
+ with st.spinner("Generating response..."):
179
+ agent = CodeAgent(tools=[random_comic], model=model)
180
+ response = agent.run(query if query else "Tell me about this XKCD comic.")
181
+ st.markdown("### AI Response")
182
+ st.markdown(response)
183
+
184
+ elif tool_choice == "Prime Number Checker":
185
+ st.header("Prime Number Checker")
186
+ st.markdown("Check if a number is prime and get a creative explanation")
187
+
188
+ number = st.number_input("Enter a number to check:", min_value=1, step=1, value=23)
189
+ explanation_style = st.selectbox(
190
+ "Choose explanation style:",
191
+ ["Poetic", "Nursery Rhyme", "Scientific", "Humorous", "Historical"]
192
+ )
193
+
194
+ if st.button("Check Prime"):
195
+ with st.spinner("Checking and generating response..."):
196
+ is_prime = prime_check_tool.forward(int(number))
197
+
198
+ # Format query based on selected style
199
+ query = f"Check if the number {number} is a prime number and explain it in a {explanation_style.lower()} style."
200
+
201
+ agent = CodeAgent(tools=[prime_check_tool], model=model)
202
+ response = agent.run(query)
203
+
204
+ # Display result with some styling
205
+ prime_status = "✅ PRIME" if is_prime else "❌ NOT PRIME"
206
+ st.markdown(f"### Result: {prime_status}")
207
+
208
+ st.markdown("### AI Explanation")
209
+ st.markdown(response)
210
+
211
+ # Optional: Show a mathematical representation
212
+ if st.checkbox("Show mathematical details"):
213
+ if is_prime:
214
+ st.markdown(f"{number} has no factors other than 1 and itself.")
215
+ else:
216
+ # Find the factors
217
+ factors = [i for i in range(1, number + 1) if number % i == 0]
218
+ st.markdown(f"Factors of {number}: {', '.join(map(str, factors))}")
219
+
220
+ # Add footer
221
+ st.sidebar.divider()
222
+ st.sidebar.markdown("Made with ❤️ using SmolaAgents")