Fola-AI commited on
Commit
ad9ebf7
Β·
verified Β·
1 Parent(s): 13a9158

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +596 -0
app.py ADDED
@@ -0,0 +1,596 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # # Chatbot Program
5
+ #
6
+ # #### Chatbot with Evaluator - Hugging Face Deployment Ready
7
+ # - Primary Agent: Google Gemini (via OpenAI API)
8
+ # - Evaluator: Groq Llama 3.3 70B
9
+ # - Fast API-based inference (no local models)
10
+
11
+ # In[ ]:
12
+
13
+
14
+ # imports
15
+
16
+ import os
17
+ import gradio as gr
18
+ from openai import OpenAI
19
+ import time
20
+ from typing import Tuple, Optional
21
+ import json
22
+ from dotenv import load_dotenv
23
+
24
+
25
+ # In[ ]:
26
+
27
+
28
+ load_dotenv(override=True)
29
+
30
+
31
+ # In[ ]:
32
+
33
+
34
+ # Check for API keys
35
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
36
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
37
+
38
+ if GOOGLE_API_KEY:
39
+ print(f"Google API Key exists and begins {GOOGLE_API_KEY[:2]}")
40
+ else:
41
+ print("Google API Key not set (and this is optional)")
42
+
43
+ if GROQ_API_KEY:
44
+ print(f"Groq API Key exists and begins {GROQ_API_KEY[:4]}")
45
+ else:
46
+ print("Groq API Key not set (and this is optional)")
47
+
48
+
49
+ # In[ ]:
50
+
51
+
52
+ # Model configurations
53
+ AGENT_MODELS = {
54
+ # "Gemini Pro": {
55
+ # "model": "gemini-pro",
56
+ # "description": "Google's Gemini Pro model",
57
+ # "max_tokens": 2048
58
+ # },
59
+ "Gemini 1.5 flash": {
60
+ "model": "gemini-1.5-flash",
61
+ "description": "Fast Gemini model",
62
+ "max_tokens": 2048
63
+ }
64
+ # "Gemini 1.5 Pro": {
65
+ # "model": "gemini-1.5-pro",
66
+ # "description": "Advanced Gemini model",
67
+ # "max_tokens": 2048
68
+ # }
69
+ }
70
+
71
+ EVALUATOR_MODELS = {
72
+ "Llama 3.3 70B": {
73
+ "model": "llama-3.3-70b-versatile",
74
+ "description": "Groq's Llama 3.3 70B - Fast & Powerful"
75
+ }
76
+ # "Llama 3.1 70B": {
77
+ # "model": "llama-3.1-70b-versatile",
78
+ # "description": "Groq's Llama 3.1 70B"
79
+ # },
80
+ # "Mixtral 8x7B": {
81
+ # "model": "mixtral-8x7b-32768",
82
+ # "description": "Groq's Mixtral model"
83
+ # }
84
+ }
85
+
86
+
87
+ # In[ ]:
88
+
89
+
90
+ # ===========================
91
+ # API Client Management Class
92
+ # ===========================
93
+
94
+ class APIClientManager:
95
+ def __init__(self):
96
+ self.gemini_client = None
97
+ self.groq_client = None
98
+ self.errors = []
99
+ self.initialize_clients()
100
+
101
+ def initialize_clients(self):
102
+ """Initialize API clients with error handling."""
103
+ # Get API keys from environment
104
+ google_api_key = os.getenv("GOOGLE_API_KEY")
105
+ groq_api_key = os.getenv("GROQ_API_KEY")
106
+
107
+ # Initialize Gemini client
108
+ if google_api_key:
109
+ try:
110
+ self.gemini_client = OpenAI(
111
+ api_key=google_api_key,
112
+ base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
113
+ )
114
+ print("βœ… Gemini API client initialized")
115
+ except Exception as e:
116
+ self.errors.append(f"Gemini initialization error: {e}")
117
+ else:
118
+ self.errors.append("GOOGLE_API_KEY not found in environment variables")
119
+
120
+ # Initialize Groq client
121
+ if groq_api_key:
122
+ try:
123
+ self.groq_client = OpenAI(
124
+ api_key=groq_api_key,
125
+ base_url="https://api.groq.com/openai/v1"
126
+ )
127
+ print("βœ… Groq API client initialized")
128
+ except Exception as e:
129
+ self.errors.append(f"Groq initialization error: {e}")
130
+ else:
131
+ self.errors.append("GROQ_API_KEY not found in environment variables")
132
+
133
+ def create_evaluator_prompt(self, user_input: str, agent_response: str) -> str:
134
+ """Create the evaluation prompt."""
135
+ evaluator_prompt = (
136
+ "You are an evaluator that decides whether a response to a question is acceptable. "
137
+ "You are provided with a conversation between a User and an Agent. "
138
+ "Your task is to decide whether the Agent's latest response is acceptable quality.\n\n"
139
+ f"User Question: {user_input}\n\n"
140
+ f"Agent Response: {agent_response}\n\n"
141
+ "With this context, please evaluate the latest response, replying with whether the response is acceptable and your feedback.\n\n"
142
+ "Format your evaluation as follows:\n"
143
+ "1. Start with either 'ACCEPTABLE βœ…' or 'UNACCEPTABLE ❌'\n"
144
+ "2. Provide a brief quality score (1-10)\n"
145
+ "3. List 2-3 specific strengths or issues\n"
146
+ "4. Suggest one improvement if needed"
147
+ )
148
+ return evaluator_prompt
149
+
150
+ def generate_agent_response(
151
+ self,
152
+ user_input: str,
153
+ model_name: str = "Gemini 1.5 flash",
154
+ temperature: float = 0.7,
155
+ max_tokens: int = 500
156
+ ) -> Tuple[str, str, float]:
157
+ """Generate response using Gemini API."""
158
+
159
+ if not self.gemini_client:
160
+ return "❌ Gemini API not initialized. Please set GOOGLE_API_KEY environment variable.", "Error", 0
161
+
162
+ try:
163
+ model_config = AGENT_MODELS.get(model_name, AGENT_MODELS["Gemini 1.5 flash"])
164
+ model_id = model_config["model"]
165
+
166
+ # Make API call to Gemini
167
+ start_time = time.time()
168
+
169
+ response = self.gemini_client.chat.completions.create(
170
+ model=model_id,
171
+ messages=[
172
+ {"role": "system", "content": "You are a helpful AI assistant. Provide clear, accurate, and helpful responses."},
173
+ {"role": "user", "content": user_input}
174
+ ],
175
+ temperature=temperature,
176
+ max_tokens=min(max_tokens, model_config["max_tokens"]),
177
+ top_p=0.9
178
+ )
179
+
180
+ elapsed_time = time.time() - start_time
181
+
182
+ # Extract response
183
+ agent_response = response.choices[0].message.content
184
+ status = f"βœ… {model_name} responded in {elapsed_time:.2f}s"
185
+
186
+ return agent_response, status, elapsed_time
187
+
188
+ except Exception as e:
189
+ error_msg = f"❌ Gemini API error: {str(e)}"
190
+ print(error_msg)
191
+
192
+ # Check for common errors
193
+ if "API key" in str(e):
194
+ error_msg = "❌ Invalid Google API key. Please check GOOGLE_API_KEY."
195
+ elif "quota" in str(e).lower():
196
+ error_msg = "❌ API quota exceeded. Please try again later."
197
+ elif "model" in str(e).lower():
198
+ error_msg = f"❌ Model '{model_name}' not available. Try another model."
199
+
200
+ return error_msg, "Error", 0
201
+
202
+ def evaluate_response(
203
+ self,
204
+ user_input: str,
205
+ agent_response: str,
206
+ evaluator_model: str = "Llama 3.3 70B",
207
+ temperature: float = 0.3
208
+ ) -> Tuple[str, str, float]:
209
+ """Evaluate the agent's response using Groq API."""
210
+
211
+ if not self.groq_client:
212
+ return "❌ Groq API not initialized. Please set GROQ_API_KEY environment variable.", "Error", 0
213
+
214
+ try:
215
+ model_config = EVALUATOR_MODELS.get(evaluator_model, EVALUATOR_MODELS["Llama 3.3 70B"])
216
+ model_id = model_config["model"]
217
+
218
+ # Create evaluation prompt using the class method
219
+ eval_prompt = self.create_evaluator_prompt(user_input, agent_response)
220
+
221
+ # Make API call to Groq
222
+ start_time = time.time()
223
+
224
+ response = self.groq_client.chat.completions.create(
225
+ model=model_id,
226
+ messages=[
227
+ {"role": "system", "content": "You are a critical evaluator. Be honest but constructive in your feedback."},
228
+ {"role": "user", "content": eval_prompt}
229
+ ],
230
+ temperature=temperature,
231
+ max_tokens=300,
232
+ top_p=0.9
233
+ )
234
+
235
+ elapsed_time = time.time() - start_time
236
+
237
+ # Extract evaluation
238
+ evaluation = response.choices[0].message.content
239
+
240
+ # Determine status based on evaluation
241
+ if "ACCEPTABLE" in evaluation.upper():
242
+ status = f"βœ… Evaluation: Acceptable | {evaluator_model} ({elapsed_time:.2f}s)"
243
+ elif "UNACCEPTABLE" in evaluation.upper():
244
+ status = f"❌ Evaluation: Needs Improvement | {evaluator_model} ({elapsed_time:.2f}s)"
245
+ else:
246
+ status = f"πŸ” Evaluation Complete | {evaluator_model} ({elapsed_time:.2f}s)"
247
+
248
+ return evaluation, status, elapsed_time
249
+
250
+ except Exception as e:
251
+ error_msg = f"❌ Groq API error: {str(e)}"
252
+ print(error_msg)
253
+
254
+ # Check for common errors
255
+ if "API key" in str(e):
256
+ error_msg = "❌ Invalid Groq API key. Please check GROQ_API_KEY."
257
+ elif "rate" in str(e).lower():
258
+ error_msg = "❌ Rate limit exceeded. Please wait a moment and try again."
259
+ elif "model" in str(e).lower():
260
+ error_msg = f"❌ Model '{evaluator_model}' not available."
261
+
262
+ return error_msg, "Error", 0
263
+
264
+
265
+ # In[ ]:
266
+
267
+
268
+ # ===========================
269
+ # Initialize Global Client Manager
270
+ # ===========================
271
+
272
+ api_manager = APIClientManager()
273
+
274
+
275
+ # In[ ]:
276
+
277
+
278
+ # ===========================
279
+ # Main Processing Function
280
+ # ===========================
281
+
282
+ def process_with_evaluation(
283
+ user_input: str,
284
+ agent_model: str,
285
+ evaluator_model: str,
286
+ temperature: float,
287
+ max_tokens: int,
288
+ enable_evaluation: bool
289
+ ) -> Tuple[str, str, str, str]:
290
+ """Process user input through agent and optionally evaluate."""
291
+
292
+ if not user_input.strip():
293
+ return "Please enter a message.", "", "No input provided", ""
294
+
295
+ # Step 1: Generate agent response
296
+ agent_response, agent_status, agent_time = api_manager.generate_agent_response(
297
+ user_input,
298
+ agent_model,
299
+ temperature,
300
+ max_tokens
301
+ )
302
+
303
+ # Step 2: Evaluate response (if enabled)
304
+ if enable_evaluation and "Error" not in agent_status:
305
+ evaluation, eval_status, eval_time = api_manager.evaluate_response(
306
+ user_input,
307
+ agent_response,
308
+ evaluator_model,
309
+ temperature=0.3 # Lower temp for evaluation
310
+ )
311
+
312
+ # Combine status
313
+ total_time = agent_time + eval_time
314
+ combined_status = f"Agent: {agent_model} ({agent_time:.2f}s) | Evaluator: {evaluator_model} ({eval_time:.2f}s) | Total: {total_time:.2f}s"
315
+
316
+ # Format evaluation for better display
317
+ if "ACCEPTABLE" in evaluation.upper():
318
+ eval_summary = "βœ… Response Quality: ACCEPTABLE"
319
+ elif "UNACCEPTABLE" in evaluation.upper():
320
+ eval_summary = "❌ Response Quality: NEEDS IMPROVEMENT"
321
+ else:
322
+ eval_summary = "πŸ” Evaluation Complete"
323
+
324
+ else:
325
+ evaluation = "Evaluation disabled or skipped due to error" if not enable_evaluation else "Skipped due to agent error"
326
+ eval_summary = "πŸ”• No evaluation performed"
327
+ combined_status = agent_status
328
+
329
+ return agent_response, evaluation, combined_status, eval_summary
330
+
331
+
332
+ # In[ ]:
333
+
334
+
335
+ # ===========================
336
+ # Gradio Interface
337
+ # ===========================
338
+
339
+ def create_interface():
340
+ """Create the Gradio interface."""
341
+
342
+ css = """
343
+ .gradio-container { max-width: 1400px !important; margin: auto; }
344
+ .response-box { background: #f0f9ff; border-left: 4px solid #3b82f6; padding: 12px; border-radius: 8px; }
345
+ .evaluation-box { background: #fef3c7; border-left: 4px solid #f59e0b; padding: 12px; border-radius: 8px; }
346
+ .status-box { font-family: monospace; font-size: 12px; color: #6b7280; }
347
+ .error-box { background: #fee2e2; border-left: 4px solid #ef4444; padding: 12px; border-radius: 8px; }
348
+ .success-indicator { color: #10b981; font-weight: bold; }
349
+ .warning-indicator { color: #f59e0b; font-weight: bold; }
350
+ """
351
+
352
+ with gr.Blocks(
353
+ title="AI Chatbot with Cross-Model Evaluator",
354
+ theme=gr.themes.Soft(),
355
+ css=css
356
+ ) as demo:
357
+
358
+ # Header
359
+ gr.Markdown("""
360
+ # πŸ€– AI Chatbot with Cross-Model Evaluator
361
+ ### **Agent:** Google Gemini 1.5 flash | **Evaluator:** Groq Llama 3.3 70B
362
+
363
+ This system uses two different AI models:
364
+ 1. **Gemini** generates responses to your questions
365
+ 2. **Llama 70B** evaluates the quality of those responses
366
+ """)
367
+
368
+ # API Status
369
+ if api_manager.errors:
370
+ with gr.Group():
371
+ gr.Markdown("### ⚠️ Setup Issues:")
372
+ for error in api_manager.errors:
373
+ gr.Markdown(f"- {error}")
374
+ gr.Markdown("""
375
+ **To fix:**
376
+ ```bash
377
+ export GOOGLE_API_KEY="your-google-api-key"
378
+ export GROQ_API_KEY="your-groq-api-key"
379
+ ```
380
+ Get keys from:
381
+ - [Google AI Studio](https://makersuite.google.com/app/apikey)
382
+ - [Groq Console](https://console.groq.com/keys)
383
+ """)
384
+ else:
385
+ gr.Markdown("βœ… **All API clients initialized successfully**")
386
+
387
+ with gr.Row():
388
+ # Left Column - Input Controls
389
+ with gr.Column(scale=2):
390
+ # Model Selection
391
+ with gr.Group():
392
+ gr.Markdown("### 🎯 Model Selection")
393
+ agent_model = gr.Dropdown(
394
+ choices=list(AGENT_MODELS.keys()),
395
+ value="Gemini 1.5 flash",
396
+ label="Agent Model (Response Generator)",
397
+ info="Google Gemini model for generating responses"
398
+ )
399
+
400
+ evaluator_model = gr.Dropdown(
401
+ choices=list(EVALUATOR_MODELS.keys()),
402
+ value="Llama 3.3 70B",
403
+ label="Evaluator Model",
404
+ info="Groq model for evaluating response quality"
405
+ )
406
+
407
+ # User Input
408
+ user_input = gr.Textbox(
409
+ lines=4,
410
+ placeholder="Ask me anything... For example: 'Explain quantum computing in simple terms'",
411
+ label="πŸ’¬ Your Question",
412
+ max_lines=8
413
+ )
414
+
415
+ # Settings
416
+ with gr.Group():
417
+ gr.Markdown("### βš™οΈ Generation Settings")
418
+ with gr.Row():
419
+ temperature = gr.Slider(
420
+ minimum=0.1,
421
+ maximum=1.0,
422
+ value=0.7,
423
+ step=0.1,
424
+ label="Temperature (Creativity)",
425
+ info="Higher = more creative, Lower = more focused"
426
+ )
427
+ max_tokens = gr.Slider(
428
+ minimum=50,
429
+ maximum=1000,
430
+ value=500,
431
+ step=50,
432
+ label="Max Tokens",
433
+ info="Maximum response length"
434
+ )
435
+
436
+ enable_evaluation = gr.Checkbox(
437
+ value=True,
438
+ label="πŸ” Enable Cross-Model Evaluation",
439
+ info="Let Llama 70B evaluate Gemini's response"
440
+ )
441
+
442
+ # Action Buttons
443
+ with gr.Row():
444
+ generate_btn = gr.Button(
445
+ "πŸš€ Generate & Evaluate",
446
+ variant="primary",
447
+ size="lg"
448
+ )
449
+ clear_btn = gr.Button("πŸ—‘οΈ Clear All", size="lg")
450
+
451
+ # Right Column - Outputs
452
+ with gr.Column(scale=3):
453
+ # Quality Indicator
454
+ quality_indicator = gr.Textbox(
455
+ label="πŸ“Š Response Quality",
456
+ interactive=False,
457
+ lines=1
458
+ )
459
+
460
+ # Agent Response
461
+ with gr.Group():
462
+ gr.Markdown("### πŸ€– Agent Response")
463
+ agent_output = gr.Textbox(
464
+ lines=10,
465
+ label="Gemini's Response",
466
+ show_copy_button=True,
467
+ interactive=False,
468
+ elem_classes=["response-box"]
469
+ )
470
+
471
+ # Evaluation
472
+ with gr.Group():
473
+ gr.Markdown("### πŸ” Evaluation Result")
474
+ evaluation_output = gr.Textbox(
475
+ lines=8,
476
+ label="Llama's Evaluation",
477
+ show_copy_button=True,
478
+ interactive=False,
479
+ elem_classes=["evaluation-box"]
480
+ )
481
+
482
+ # Status
483
+ status_output = gr.Textbox(
484
+ lines=2,
485
+ label="⏱️ Performance Metrics",
486
+ interactive=False,
487
+ elem_classes=["status-box"]
488
+ )
489
+
490
+ # Examples
491
+ with gr.Row():
492
+ gr.Examples(
493
+ examples=[
494
+ ["What is the difference between machine learning and deep learning?"],
495
+ ["Write a Python function to calculate the factorial of a number"],
496
+ ["Explain the theory of relativity in simple terms"],
497
+ ["What are the main causes of climate change?"],
498
+ ["How does blockchain technology work?"],
499
+ ["What are the benefits and risks of artificial intelligence?"]
500
+ ],
501
+ inputs=user_input,
502
+ label="πŸ’‘ Example Questions"
503
+ )
504
+
505
+ # How It Works
506
+ with gr.Accordion("ℹ️ How Cross-Model Evaluation Works", open=False):
507
+ gr.Markdown("""
508
+ ### The Two-Stage Process:
509
+
510
+ **1. Response Generation (Gemini)**
511
+ - Receives your question
512
+ - Generates a comprehensive response
513
+ - Optimized for helpfulness and accuracy
514
+
515
+ **2. Quality Evaluation (Llama 70B)**
516
+ - Analyzes the response for:
517
+ - Accuracy and completeness
518
+ - Clarity and coherence
519
+ - Potential issues or biases
520
+ - Provides feedback and improvement suggestions
521
+
522
+ ### Benefits:
523
+ - βœ… **Quality Assurance**: Second model checks for errors
524
+ - βœ… **Bias Detection**: Different model perspectives
525
+ - βœ… **Improvement Insights**: Specific feedback on responses
526
+ - βœ… **Fast Processing**: API-based, no local model loading
527
+
528
+ ### API Requirements:
529
+ - Google API Key for Gemini (free tier available)
530
+ - Groq API Key for Llama (free tier available)
531
+ """)
532
+
533
+ # Event Handlers
534
+ generate_btn.click(
535
+ fn=process_with_evaluation,
536
+ inputs=[user_input, agent_model, evaluator_model, temperature, max_tokens, enable_evaluation],
537
+ outputs=[agent_output, evaluation_output, status_output, quality_indicator]
538
+ )
539
+
540
+ clear_btn.click(
541
+ fn=lambda: ("", "", "", ""),
542
+ outputs=[user_input, agent_output, evaluation_output, status_output]
543
+ )
544
+
545
+ user_input.submit(
546
+ fn=process_with_evaluation,
547
+ inputs=[user_input, agent_model, evaluator_model, temperature, max_tokens, enable_evaluation],
548
+ outputs=[agent_output, evaluation_output, status_output, quality_indicator]
549
+ )
550
+
551
+ return demo
552
+
553
+
554
+ # In[ ]:
555
+
556
+
557
+ # ===========================
558
+ # Main Execution
559
+ # ===========================
560
+
561
+ if __name__ == "__main__":
562
+ print("=" * 60)
563
+ print("πŸš€ AI Chatbot with Cross-Model Evaluator")
564
+ print("=" * 60)
565
+
566
+ # Check API keys
567
+ google_key = os.getenv("GOOGLE_API_KEY")
568
+ groq_key = os.getenv("GROQ_API_KEY")
569
+
570
+ if not google_key:
571
+ print("⚠️ Warning: GOOGLE_API_KEY not found")
572
+ print(" Set it with: export GOOGLE_API_KEY='your-key-here'")
573
+ else:
574
+ print(f"βœ… Google API Key detected: {google_key[:10]}...")
575
+
576
+ if not groq_key:
577
+ print("⚠️ Warning: GROQ_API_KEY not found")
578
+ print(" Set it with: export GROQ_API_KEY='your-key-here'")
579
+ else:
580
+ print(f"βœ… Groq API Key detected: {groq_key[:10]}...")
581
+
582
+ print("=" * 60)
583
+ print("πŸ“ Starting Gradio interface...")
584
+ print("πŸ“Œ Interface will be available at: http://localhost:7860")
585
+ print("=" * 60)
586
+
587
+ # Create and launch interface
588
+ demo = create_interface()
589
+ demo.launch()
590
+
591
+
592
+ # In[ ]:
593
+
594
+
595
+
596
+