vighnesh-shetty-vs commited on
Commit
88d4a8f
Β·
1 Parent(s): f55bc01

Add updated files

Browse files
Files changed (2) hide show
  1. app.py +235 -30
  2. requirements.txt +2 -1
app.py CHANGED
@@ -1,13 +1,18 @@
1
  import gradio as gr
2
  from transformers import pipeline
 
 
 
 
 
3
  from game_data import calculate_impact
 
 
4
 
5
- # Load zero-shot classification pipeline
6
- # (This runs server-side and uses the free CPU tier effectively)
7
  print("Loading classification model (facebook/bart-large-mnli)...")
8
  classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
9
 
10
- # Predefined categories mapping to your zero-shot labels
11
  CATEGORIES = [
12
  "simple factual question",
13
  "mathematical calculation",
@@ -15,43 +20,243 @@ CATEGORIES = [
15
  "complex research query"
16
  ]
17
 
18
- def classify_query(user_input):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  """
20
- Takes user input, classifies it using zero-shot classification,
21
- and returns the highest probability category and its confidence score.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  """
23
- result = classifier(user_input, CATEGORIES)
24
- top_category = result['labels'][0]
25
- confidence_score = result['scores'][0]
 
 
 
 
26
 
27
- return top_category, confidence_score
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
- def process_query(user_input):
30
- """Processes the query for the Gradio interface."""
31
- category, confidence = classify_query(user_input)
 
 
 
 
 
 
 
 
32
  impact = calculate_impact(category, confidence, user_input)
33
 
34
- result_text = (
35
- f"**Category:** {category}\n"
36
- f"**Confidence:** {confidence:.2f}\n"
37
- f"**Water Wasted:** {impact['water']}L\n"
38
- f"**Energy Wasted:** {impact['energy']}kWh"
39
- )
40
- return result_text
41
 
42
- # Create a basic Gradio interface to keep the Space alive
43
- with gr.Blocks() as demo:
44
- gr.Markdown("# πŸ’§ EcoQueryQuest (Test UI)")
45
- gr.Markdown("Type a query to see its hidden environmental cost!")
46
 
47
- with gr.Row():
48
- input_box = gr.Textbox(label="Your Query", placeholder="e.g., What is the capital of France?")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
- submit_btn = gr.Button("Analyze")
51
- output_box = gr.Markdown(label="Impact Results")
52
 
53
- submit_btn.click(fn=process_query, inputs=input_box, outputs=output_box)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- # Launch the app so it stays running on Hugging Face
56
  if __name__ == "__main__":
57
  demo.launch()
 
1
  import gradio as gr
2
  from transformers import pipeline
3
+ import random
4
+ from gtts import gTTS
5
+ import os
6
+
7
+ # Import your local modules (Ensure game_data.py, dialogues.py, alternatives.py exist in the same folder)
8
  from game_data import calculate_impact
9
+ from dialogues import get_dialogue
10
+ from alternatives import ALTERNATIVES
11
 
12
+ # --- 1. Load AI Models ---
 
13
  print("Loading classification model (facebook/bart-large-mnli)...")
14
  classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
15
 
 
16
  CATEGORIES = [
17
  "simple factual question",
18
  "mathematical calculation",
 
20
  "complex research query"
21
  ]
22
 
23
+ # --- 2. Helper Functions & UI Generators ---
24
+
25
+ def generate_audio(text):
26
+ """Generates instant TTS audio using gTTS to prevent CPU timeouts."""
27
+ tts = gTTS(text, lang='en')
28
+ filepath = "temp_drip_voice.mp3"
29
+ tts.save(filepath)
30
+ return filepath
31
+
32
+ def get_drip_visuals(water_level):
33
+ """Generates the CSS/HTML for Drip based on dehydration."""
34
+ if water_level > 70:
35
+ emoji, size, animation = "πŸ’§", "80px", "bounce 2s infinite"
36
+ status = "Plump & Hydrated"
37
+ elif 30 <= water_level <= 70:
38
+ emoji, size, animation = "πŸ’§", "60px", "none"
39
+ status = "Shrinking & Tired"
40
+ elif water_level > 0:
41
+ emoji, size, animation = "🏜️", "40px", "none"
42
+ status = "Cracked & Raspy"
43
+ else:
44
+ emoji, size, animation = "πŸ’¨", "30px", "none"
45
+ status = "Evaporated!"
46
+
47
+ return f"""
48
+ <div style="text-align: center; margin-bottom: 20px;">
49
+ <div style="font-size: {size}; animation: {animation}; transition: all 0.5s;">{emoji}</div>
50
+ <h3 style="margin: 0;">Drip Status: {status}</h3>
51
+ </div>
52
  """
53
+
54
+ def get_impact_cards(impact, category):
55
+ """Generates side-by-side comparison cards."""
56
+ # Relatable translations
57
+ water_trans = f"{impact['water']}L is like leaving a tap running for {int(impact['water']*12)} seconds."
58
+ if impact['water'] >= 5:
59
+ water_trans = f"{impact['water']}L = A whole day's drinking water for a family."
60
+
61
+ energy_trans = f"{impact['energy']}kWh could charge your phone {int(impact['energy']*100)} times."
62
+ if impact['energy'] >= 0.5:
63
+ energy_trans = f"{impact['energy']}kWh = Powering a fridge for several hours."
64
+
65
+ return f"""
66
+ <div style="display: flex; gap: 20px; justify-content: center; margin-top: 20px;">
67
+ <div style="flex: 1; padding: 15px; background: #ffebee; border-left: 5px solid #f44336; border-radius: 5px;">
68
+ <h3 style="color: #c62828; margin-top: 0;">LLM Impact (Massive Servers)</h3>
69
+ <p><strong>Water Wasted:</strong> {impact['water']}L</p>
70
+ <p><strong>Energy Wasted:</strong> {impact['energy']}kWh</p>
71
+ <p><em>{water_trans}</em></p>
72
+ <p><em>{energy_trans}</em></p>
73
+ </div>
74
+ <div style="flex: 1; padding: 15px; background: #e8f5e9; border-left: 5px solid #4caf50; border-radius: 5px;">
75
+ <h3 style="color: #2e7d32; margin-top: 0;">Eco-Alternative (Local/Search)</h3>
76
+ <p><strong>Water Wasted:</strong> ~0.0L</p>
77
+ <p><strong>Energy Wasted:</strong> ~0.001kWh</p>
78
+ <p><em>Save the planet, use appropriate tools!</em></p>
79
+ </div>
80
+ </div>
81
  """
82
+
83
+ def generate_report(state):
84
+ """Generates the final game over report."""
85
+ badges = []
86
+ if state['water'] > 50: badges.append("🌊 Water Warrior")
87
+ if state['eco_score'] >= 80: badges.append("🌿 Conscious Querier")
88
+ if not badges: badges.append("πŸ”₯ Resource Drainer")
89
 
90
+ return f"""
91
+ <div style="background: #2c3e50; color: white; padding: 30px; border-radius: 10px; text-align: center;">
92
+ <h1>Game Over! Here is your AI Audit.</h1>
93
+ <h2>Final Score: {state['points']} Points</h2>
94
+ <p>You asked {state['queries']} queries.</p>
95
+ <p><strong>Total Water Drained:</strong> {100 - state['water']:.2f}L</p>
96
+ <p><strong>Total Energy Consumed:</strong> {state['energy']:.3f}kWh</p>
97
+ <p><strong>Eco-Score:</strong> {state['eco_score']:.1f}%</p>
98
+ <h3>Badges Earned:</h3>
99
+ <h2>{' | '.join(badges)}</h2>
100
+ <p style="margin-top: 20px; font-size: 0.9em;"><em>Tip: Match the tool to the task. Don't use a supercomputer to ask for a recipe! Review the UNESCO guidelines on proportional AI usage.</em></p>
101
+ </div>
102
+ """
103
 
104
+ # --- 3. Core Game Logic ---
105
+
106
+ def process_query(user_input, state):
107
+ if state["game_over"] or not user_input.strip():
108
+ return state, gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(visible=False), gr.update(visible=False)
109
+
110
+ # 1. Classification & Impact Calculation
111
+ result = classifier(user_input, CATEGORIES)
112
+ category = result['labels'][0]
113
+ confidence = result['scores'][0]
114
+
115
  impact = calculate_impact(category, confidence, user_input)
116
 
117
+ # 2. Update Basic State
118
+ state["queries"] += 1
119
+ state["water"] = max(0, state["water"] - impact["water"])
120
+ state["energy"] += impact["energy"]
121
+ state["history"].append(category)
 
 
122
 
123
+ # 3. Category Specific Logic (Points & Alternatives)
124
+ show_alts = False
125
+ alt_choices = []
126
+ correct_alt = None
127
 
128
+ if category == "complex research query":
129
+ # Justified use: +50 points, no alternatives needed
130
+ state["points"] += 50
131
+ dialogue = "Finally, a real question! This is what my servers were built for. Draining, but worth it."
132
+ else:
133
+ # Unjustified/Avoidable: Fetch alternatives
134
+ show_alts = True
135
+ alt_choices = ALTERNATIVES.get(category, ["Google", "Wikipedia", "Book"])
136
+ correct_alt = alt_choices[0] # For MVP, the first item in the list is the "best" one
137
+ random.shuffle(alt_choices) # Shuffle so it's not always button 1
138
+ state["current_best_alt"] = correct_alt
139
+
140
+ # Get sarcastic Drip dialogue based on water level
141
+ dialogue = get_dialogue(state["water"], category)
142
+
143
+ # 4. Generate outputs
144
+ drip_ui = get_drip_visuals(state["water"])
145
+ impact_ui = get_impact_cards(impact, category)
146
+ audio_path = generate_audio(dialogue)
147
+
148
+ # Check Win/Loss
149
+ if state["points"] >= 500 or state["water"] <= 0:
150
+ state["game_over"] = True
151
+ return (state, drip_ui, gr.update(value=state["water"]), gr.update(value=f"{state['energy']:.3f} kWh"),
152
+ generate_report(state), gr.update(visible=False), audio_path, gr.update(visible=False), gr.update(visible=False))
153
+
154
+ # Return updated UI components
155
+ if show_alts:
156
+ return (state, drip_ui, gr.update(value=state["water"]), gr.update(value=f"{state['energy']:.3f} kWh"),
157
+ impact_ui, gr.update(value=f"**{category.upper()}** Detected! {dialogue}"), audio_path,
158
+ gr.update(visible=True), gr.update(value=alt_choices[0]), gr.update(value=alt_choices[1]), gr.update(value=alt_choices[2]))
159
+ else:
160
+ return (state, drip_ui, gr.update(value=state["water"]), gr.update(value=f"{state['energy']:.3f} kWh"),
161
+ impact_ui, gr.update(value=f"**{category.upper()}** Detected! {dialogue}"), audio_path,
162
+ gr.update(visible=False), gr.update(), gr.update(), gr.update())
163
+
164
+
165
+ def select_alternative(choice, state):
166
+ """Handles logic when a user clicks an Eco-Alternative button."""
167
+ if state["game_over"] or not state.get("current_best_alt"):
168
+ return state, gr.update()
169
+
170
+ msg = ""
171
+ if choice == state["current_best_alt"]:
172
+ state["points"] += 10
173
+ state["eco_choices"] += 1
174
+ msg = "βœ… **Great choice!** You earned +10 Eco Points for picking the right tool for the job."
175
+ else:
176
+ msg = "❌ **Not quite.** That works, but there was a better eco-friendly option. Still better than an LLM though!"
177
 
178
+ # Update Eco-Score
179
+ state["eco_score"] = (state["eco_choices"] / state["queries"]) * 100 if state["queries"] > 0 else 0
180
 
181
+ # Hide alternatives after selection
182
+ return state, gr.update(value=msg), gr.update(visible=False)
183
+
184
+
185
+ # --- 4. Gradio Interface Layout ---
186
+
187
+ custom_css = """
188
+ .gradio-container { max-width: 800px !important; margin: auto; }
189
+ .progress-bar-container { background: #e0e0e0; border-radius: 10px; height: 30px; width: 100%; overflow: hidden; margin-top: 5px; }
190
+ .progress-bar { background: #2196f3; height: 100%; transition: width 0.5s ease-in-out; }
191
+ """
192
+
193
+ with gr.Blocks(css=custom_css, title="EcoQueryQuest") as demo:
194
+
195
+ # Initialize Game State
196
+ game_state = gr.State({
197
+ "water": 100.0, "energy": 0.0, "points": 0, "queries": 0,
198
+ "eco_choices": 0, "eco_score": 0.0, "history": [], "game_over": False,
199
+ "current_best_alt": None
200
+ })
201
+
202
+ gr.Markdown("# 🌍 EcoQueryQuest")
203
+ gr.Markdown("Type your query below. Watch Drip (πŸ’§) react to the environmental cost of your prompt! Reach 500 points to win, but don't run out of water.")
204
+
205
+ # TOP SECTION: Visuals & Trackers
206
+ with gr.Row():
207
+ with gr.Column(scale=1):
208
+ drip_html = gr.HTML(get_drip_visuals(100))
209
+ with gr.Column(scale=2):
210
+ gr.Markdown("### 🚰 Water Tank (100L Limit)")
211
+ water_slider = gr.Slider(minimum=0, maximum=100, value=100, interactive=False, show_label=False)
212
+ gr.Markdown("### ⚑ Energy Wasted")
213
+ energy_text = gr.Textbox(value="0.000 kWh", interactive=False, show_label=False)
214
+ gr.Markdown("### πŸ† Points")
215
+ points_text = gr.Textbox(value="0", interactive=False, show_label=False)
216
+
217
+ # MIDDLE SECTION: Interaction
218
+ with gr.Group() as interaction_group:
219
+ user_input = gr.Textbox(label="Ask an AI a question...", placeholder="e.g., What is 25 * 42? or Write me a poem about dogs.")
220
+ submit_btn = gr.Button("Send Query", variant="primary")
221
+
222
+ main_display_html = gr.HTML()
223
+ drip_dialogue_text = gr.Markdown()
224
+ drip_audio = gr.Audio(label="Drip's Reaction", autoplay=True, interactive=False)
225
+
226
+ # BOTTOM SECTION: Alternatives (Hidden by default)
227
+ with gr.Group(visible=False) as alternatives_group:
228
+ gr.Markdown("### ⏳ Drip says: 'Choose a better alternative to save me!'")
229
+ with gr.Row():
230
+ alt_btn_1 = gr.Button("Alt 1")
231
+ alt_btn_2 = gr.Button("Alt 2")
232
+ alt_btn_3 = gr.Button("Alt 3")
233
+ alt_feedback = gr.Markdown()
234
+
235
+ # EVENT WIRING
236
+
237
+ # 1. Submit Query
238
+ submit_btn.click(
239
+ fn=process_query,
240
+ inputs=[user_input, game_state],
241
+ outputs=[game_state, drip_html, water_slider, energy_text, main_display_html, drip_dialogue_text, drip_audio, alternatives_group, alt_btn_1, alt_btn_2, alt_btn_3]
242
+ ).then(
243
+ fn=lambda s: gr.update(value=str(s["points"])), # Update points UI after processing
244
+ inputs=[game_state],
245
+ outputs=[points_text]
246
+ )
247
+
248
+ # 2. Click Alternative Buttons
249
+ for btn in [alt_btn_1, alt_btn_2, alt_btn_3]:
250
+ btn.click(
251
+ fn=select_alternative,
252
+ inputs=[btn, game_state],
253
+ outputs=[game_state, alt_feedback, alternatives_group]
254
+ ).then(
255
+ fn=lambda s: gr.update(value=str(s["points"])), # Update points UI after clicking alternative
256
+ inputs=[game_state],
257
+ outputs=[points_text]
258
+ )
259
 
260
+ # Launch the app
261
  if __name__ == "__main__":
262
  demo.launch()
requirements.txt CHANGED
@@ -1,4 +1,5 @@
1
  gradio
2
  transformers
3
  torch
4
- Pillow
 
 
1
  gradio
2
  transformers
3
  torch
4
+ Pillow
5
+ gTTS