Spaces:
Runtime error
Runtime error
Commit
Β·
30fae6f
1
Parent(s):
c4cb380
FINAL FIX: @tool decorator error resolved + optimized deps
Browse files- app.py +252 -180
- requirements.txt +0 -0
app.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
#!/usr/bin/env python3
|
2 |
"""
|
3 |
-
AI-Powered Personal Learning Assistant
|
4 |
-
Clean Production Build for HuggingFace Spaces
|
5 |
Gradio Agents & MCP Hackathon 2025
|
6 |
|
7 |
Features:
|
8 |
- Multi-agent AI reasoning with smolagents
|
9 |
-
- Voice AI processing with SambaNova Cloud
|
10 |
- Real-time data integration via MCP
|
11 |
- ZeroGPU optimized for HuggingFace Spaces
|
12 |
"""
|
@@ -26,9 +26,10 @@ from datetime import datetime, timedelta
|
|
26 |
import gradio as gr
|
27 |
import requests
|
28 |
import plotly.graph_objects as go
|
|
|
29 |
from dotenv import load_dotenv
|
30 |
|
31 |
-
# Audio processing
|
32 |
try:
|
33 |
import speech_recognition as sr
|
34 |
import pydub
|
@@ -38,12 +39,13 @@ except ImportError as e:
|
|
38 |
AUDIO_AVAILABLE = False
|
39 |
print(f"β οΈ Audio libraries not available: {e}")
|
40 |
|
41 |
-
# AI dependencies with graceful fallbacks
|
42 |
try:
|
43 |
import transformers
|
44 |
TRANSFORMERS_AVAILABLE = True
|
45 |
except ImportError:
|
46 |
TRANSFORMERS_AVAILABLE = False
|
|
|
47 |
|
48 |
try:
|
49 |
import smolagents
|
@@ -53,12 +55,23 @@ except ImportError:
|
|
53 |
SMOLAGENTS_AVAILABLE = False
|
54 |
print("β οΈ Smolagents not available - using fallback mode")
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
# HuggingFace Spaces support
|
57 |
try:
|
58 |
import spaces
|
59 |
SPACES_AVAILABLE = True
|
60 |
except ImportError:
|
61 |
SPACES_AVAILABLE = False
|
|
|
62 |
class spaces:
|
63 |
@staticmethod
|
64 |
def GPU(func):
|
@@ -69,17 +82,17 @@ load_dotenv()
|
|
69 |
logging.basicConfig(level=logging.INFO)
|
70 |
logger = logging.getLogger(__name__)
|
71 |
|
72 |
-
#
|
73 |
SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY")
|
74 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
75 |
SAMBANOVA_AVAILABLE = bool(SAMBANOVA_API_KEY)
|
76 |
|
77 |
# ============================================================================
|
78 |
-
# Database Layer
|
79 |
# ============================================================================
|
80 |
|
81 |
class LearningDatabase:
|
82 |
-
"""SQLite database for learning progress
|
83 |
|
84 |
def __init__(self, db_path: str = "learning_assistant.db"):
|
85 |
self.db_path = db_path
|
@@ -91,6 +104,7 @@ class LearningDatabase:
|
|
91 |
with sqlite3.connect(self.db_path) as conn:
|
92 |
cursor = conn.cursor()
|
93 |
|
|
|
94 |
cursor.execute("""
|
95 |
CREATE TABLE IF NOT EXISTS user_profiles (
|
96 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
@@ -101,6 +115,7 @@ class LearningDatabase:
|
|
101 |
)
|
102 |
""")
|
103 |
|
|
|
104 |
cursor.execute("""
|
105 |
CREATE TABLE IF NOT EXISTS learning_sessions (
|
106 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
@@ -114,6 +129,19 @@ class LearningDatabase:
|
|
114 |
)
|
115 |
""")
|
116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
conn.commit()
|
118 |
logger.info("β
Database initialized successfully")
|
119 |
|
@@ -121,7 +149,7 @@ class LearningDatabase:
|
|
121 |
logger.error(f"β Database initialization failed: {e}")
|
122 |
|
123 |
# ============================================================================
|
124 |
-
# Multi-Agent System with Smolagents
|
125 |
# ============================================================================
|
126 |
|
127 |
class LearningAgents:
|
@@ -139,36 +167,77 @@ class LearningAgents:
|
|
139 |
return
|
140 |
|
141 |
try:
|
142 |
-
# Initialize
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
|
148 |
# Create specialized agents
|
149 |
-
self.curriculum_agent =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
tools=[self.curriculum_planning_tool],
|
151 |
model=model,
|
152 |
max_iterations=3
|
153 |
)
|
154 |
-
|
155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
tools=[self.content_generation_tool],
|
157 |
model=model,
|
158 |
max_iterations=2
|
159 |
)
|
160 |
-
|
161 |
-
logger.info("β
Smolagents multi-agent system initialized")
|
162 |
-
|
163 |
except Exception as e:
|
164 |
-
logger.error(f"
|
165 |
-
self.
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
def setup_fallback_agents(self):
|
169 |
"""Setup fallback agents when smolagents is not available"""
|
170 |
self.curriculum_agent = self.create_fallback_agent("curriculum")
|
171 |
self.content_agent = self.create_fallback_agent("content")
|
|
|
172 |
|
173 |
def create_fallback_agent(self, agent_type: str):
|
174 |
"""Create fallback agent for when smolagents is unavailable"""
|
@@ -177,147 +246,95 @@ class LearningAgents:
|
|
177 |
self.agent_type = agent_type
|
178 |
|
179 |
def run(self, prompt):
|
|
|
|
|
|
|
180 |
if self.agent_type == "curriculum":
|
181 |
return self.generate_curriculum_fallback(prompt)
|
182 |
elif self.agent_type == "content":
|
183 |
return self.generate_content_fallback(prompt)
|
|
|
|
|
184 |
else:
|
185 |
-
return "
|
186 |
-
|
187 |
-
def generate_curriculum_fallback(self, prompt):
|
188 |
-
return """
|
189 |
-
# π AI-Generated Learning Curriculum
|
190 |
-
|
191 |
-
## π― Structured Learning Path
|
192 |
-
|
193 |
-
### Phase 1: Foundation Building
|
194 |
-
- Core concepts and terminology
|
195 |
-
- Essential prerequisites review
|
196 |
-
- Hands-on introduction exercises
|
197 |
-
|
198 |
-
### Phase 2: Skill Development
|
199 |
-
- Practical application projects
|
200 |
-
- Guided practice sessions
|
201 |
-
- Real-world case studies
|
202 |
-
|
203 |
-
### Phase 3: Advanced Application
|
204 |
-
- Complex problem solving
|
205 |
-
- Integration with other topics
|
206 |
-
- Portfolio development
|
207 |
-
|
208 |
-
### π Progress Milestones
|
209 |
-
- **Week 1-2**: Foundation mastery
|
210 |
-
- **Week 3-4**: Practical application
|
211 |
-
- **Week 5-6**: Advanced projects
|
212 |
-
|
213 |
-
*Generated in fallback mode - Install smolagents for advanced reasoning*
|
214 |
-
"""
|
215 |
-
|
216 |
-
def generate_content_fallback(self, prompt):
|
217 |
-
return """
|
218 |
-
# π Learning Content
|
219 |
-
|
220 |
-
## π Overview
|
221 |
-
Educational content covering essential concepts.
|
222 |
-
|
223 |
-
## π― Key Learning Objectives
|
224 |
-
- Understand fundamental principles
|
225 |
-
- Apply concepts to real scenarios
|
226 |
-
- Develop practical skills
|
227 |
-
|
228 |
-
## π Content Structure
|
229 |
-
1. Introduction & Context
|
230 |
-
2. Core Concepts
|
231 |
-
3. Practical Examples
|
232 |
-
4. Hands-on Exercises
|
233 |
-
5. Assessment & Review
|
234 |
-
|
235 |
-
*Generated in fallback mode*
|
236 |
-
"""
|
237 |
|
238 |
return FallbackAgent(agent_type)
|
239 |
|
240 |
-
#
|
241 |
-
@tool
|
242 |
def curriculum_planning_tool(self, subject: str, level: str, goals: str) -> str:
|
243 |
-
"""
|
244 |
return f"""
|
245 |
# π AI-Generated Curriculum: {subject}
|
246 |
|
247 |
## π― Learning Path for {level.title()} Level
|
248 |
|
249 |
-
###
|
250 |
-
|
251 |
-
### Phase 1: Foundation Building (Weeks 1-2)
|
252 |
-
- Core concepts and terminology in {subject}
|
253 |
- Essential prerequisites review
|
254 |
- Hands-on introduction exercises
|
255 |
-
- Initial skill assessment
|
256 |
|
257 |
-
### Phase 2: Skill Development
|
258 |
- Practical application projects
|
259 |
- Guided practice sessions
|
260 |
-
- Real-world case studies
|
261 |
-
- Intermediate challenges
|
262 |
|
263 |
-
### Phase 3: Advanced Application
|
264 |
- Complex problem solving
|
265 |
- Integration with other topics
|
266 |
- Portfolio development
|
267 |
-
- Mastery demonstrations
|
268 |
|
269 |
### π Progress Milestones
|
270 |
-
1. **
|
271 |
-
2. **
|
272 |
-
3. **
|
273 |
-
|
274 |
-
### π Recommended Next Steps
|
275 |
-
- Advanced {subject} topics
|
276 |
-
- Related field exploration
|
277 |
-
- Professional application
|
278 |
|
279 |
-
|
280 |
"""
|
281 |
|
282 |
-
@tool
|
283 |
def content_generation_tool(self, topic: str, difficulty: str) -> str:
|
284 |
"""Content generation tool for smolagents"""
|
285 |
return f"""
|
286 |
# π Learning Content: {topic}
|
287 |
|
288 |
-
## π Overview
|
289 |
-
|
290 |
|
291 |
## π― Key Learning Objectives
|
292 |
-
-
|
293 |
-
- Apply
|
294 |
-
- Develop
|
295 |
-
- Build confidence in {topic}
|
296 |
-
|
297 |
-
## π Structured Content
|
298 |
-
|
299 |
-
### 1. Introduction & Context
|
300 |
-
Understanding the importance and applications of {topic}.
|
301 |
-
|
302 |
-
### 2. Core Concepts
|
303 |
-
Fundamental principles you need to master.
|
304 |
-
|
305 |
-
### 3. Practical Examples
|
306 |
-
Real-world applications and case studies.
|
307 |
-
|
308 |
-
### 4. Hands-on Exercises
|
309 |
-
Interactive practice opportunities.
|
310 |
|
311 |
-
|
312 |
-
|
|
|
|
|
|
|
|
|
313 |
|
314 |
## π Next Steps
|
315 |
-
|
316 |
-
- Explore advanced topics
|
317 |
-
- Apply skills to personal projects
|
318 |
-
|
319 |
-
*Generated by Smolagents Content Agent*
|
320 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
321 |
|
322 |
# ============================================================================
|
323 |
# SambaNova Audio AI Integration
|
@@ -339,13 +356,14 @@ class SambaNovaAudioAI:
|
|
339 |
if not self.available:
|
340 |
return {
|
341 |
"error": "SambaNova Audio AI not available",
|
342 |
-
"message": "Please
|
343 |
}
|
344 |
|
345 |
try:
|
346 |
-
#
|
347 |
audio_data = self.prepare_audio(audio_path)
|
348 |
|
|
|
349 |
headers = {
|
350 |
"Authorization": f"Bearer {self.api_key}",
|
351 |
"Content-Type": "application/json"
|
@@ -357,7 +375,7 @@ class SambaNovaAudioAI:
|
|
357 |
{
|
358 |
"role": "user",
|
359 |
"content": [
|
360 |
-
{"type": "text", "text": prompt or "Analyze this audio
|
361 |
{"type": "audio", "audio": audio_data}
|
362 |
]
|
363 |
}
|
@@ -391,14 +409,14 @@ class SambaNovaAudioAI:
|
|
391 |
def prepare_audio(self, audio_path: str) -> str:
|
392 |
"""Prepare audio for SambaNova API"""
|
393 |
try:
|
394 |
-
# Convert to WAV if needed
|
395 |
if not audio_path.endswith('.wav'):
|
396 |
audio = pydub.AudioSegment.from_file(audio_path)
|
397 |
wav_path = audio_path.replace(Path(audio_path).suffix, '.wav')
|
398 |
audio.export(wav_path, format="wav")
|
399 |
audio_path = wav_path
|
400 |
|
401 |
-
#
|
402 |
import base64
|
403 |
with open(audio_path, 'rb') as f:
|
404 |
audio_data = base64.b64encode(f.read()).decode('utf-8')
|
@@ -412,9 +430,10 @@ class SambaNovaAudioAI:
|
|
412 |
def generate_learning_plan_from_audio(self, audio_path: str) -> str:
|
413 |
"""Generate learning plan from audio input"""
|
414 |
prompt = """
|
415 |
-
|
|
|
416 |
1. Identified learning goals from the audio
|
417 |
-
2. Recommended curriculum structure
|
418 |
3. Timeline and milestones
|
419 |
4. Resources and next steps
|
420 |
"""
|
@@ -441,7 +460,7 @@ class SambaNovaAudioAI:
|
|
441 |
"""Answer questions from audio input"""
|
442 |
prompt = """
|
443 |
Listen to this audio question and provide a comprehensive educational answer.
|
444 |
-
|
445 |
1. Clear explanation of the concept
|
446 |
2. Practical examples
|
447 |
3. Additional learning resources
|
@@ -469,34 +488,19 @@ class SambaNovaAudioAI:
|
|
469 |
def convert_speech_to_text(self, audio_path: str) -> str:
|
470 |
"""Convert speech to text using local speech recognition"""
|
471 |
if not AUDIO_AVAILABLE:
|
472 |
-
return "β Speech recognition
|
473 |
|
474 |
try:
|
475 |
recognizer = sr.Recognizer()
|
476 |
-
|
477 |
-
# Convert audio to WAV if needed
|
478 |
-
if not audio_path.endswith('.wav'):
|
479 |
-
audio = pydub.AudioSegment.from_file(audio_path)
|
480 |
-
wav_path = audio_path.replace(Path(audio_path).suffix, '.wav')
|
481 |
-
audio.export(wav_path, format="wav")
|
482 |
-
audio_path = wav_path
|
483 |
-
|
484 |
with sr.AudioFile(audio_path) as source:
|
485 |
audio_data = recognizer.record(source)
|
486 |
text = recognizer.recognize_google(audio_data)
|
487 |
-
return f""
|
488 |
-
# π€ Speech-to-Text Result
|
489 |
-
|
490 |
-
**Transcribed Text**: {text}
|
491 |
-
|
492 |
-
---
|
493 |
-
*Local Speech Recognition*
|
494 |
-
"""
|
495 |
except Exception as e:
|
496 |
return f"β **Speech Recognition Error**: {e}"
|
497 |
|
498 |
# ============================================================================
|
499 |
-
# Main Learning Assistant
|
500 |
# ============================================================================
|
501 |
|
502 |
class LearningAssistant:
|
@@ -515,7 +519,7 @@ class LearningAssistant:
|
|
515 |
if self.agents.agents_available:
|
516 |
# Use smolagents for advanced reasoning
|
517 |
prompt = f"""
|
518 |
-
Create comprehensive curriculum for:
|
519 |
Subject: {subject}
|
520 |
Level: {level}
|
521 |
Goals: {goals}
|
@@ -526,11 +530,55 @@ class LearningAssistant:
|
|
526 |
return result
|
527 |
else:
|
528 |
# Fallback curriculum generation
|
529 |
-
return self.
|
530 |
|
531 |
except Exception as e:
|
532 |
logger.error(f"Curriculum generation error: {e}")
|
533 |
-
return f"β **Error**: {e}\n\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
534 |
|
535 |
def process_audio_learning_request(self, audio_input) -> str:
|
536 |
"""Process audio input for learning plan generation"""
|
@@ -538,9 +586,15 @@ class LearningAssistant:
|
|
538 |
return "β **Error**: No audio provided"
|
539 |
|
540 |
try:
|
|
|
541 |
audio_path = self.save_gradio_audio(audio_input)
|
|
|
|
|
542 |
result = self.audio_ai.generate_learning_plan_from_audio(audio_path)
|
|
|
|
|
543 |
self.cleanup_temp_file(audio_path)
|
|
|
544 |
return result
|
545 |
|
546 |
except Exception as e:
|
@@ -581,10 +635,13 @@ class LearningAssistant:
|
|
581 |
"""Save Gradio audio input to temporary file"""
|
582 |
try:
|
583 |
if isinstance(audio_input, str):
|
|
|
584 |
return audio_input
|
585 |
elif hasattr(audio_input, 'name'):
|
|
|
586 |
return audio_input.name
|
587 |
else:
|
|
|
588 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.wav')
|
589 |
temp_file.write(audio_input)
|
590 |
temp_file.close()
|
@@ -627,10 +684,10 @@ def create_learning_interface():
|
|
627 |
# Initialize learning assistant
|
628 |
learning_assistant = LearningAssistant()
|
629 |
|
630 |
-
# Custom CSS
|
631 |
custom_css = """
|
632 |
.gradio-container {
|
633 |
-
font-family: 'Segoe UI',
|
634 |
}
|
635 |
.main-header {
|
636 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
@@ -647,6 +704,14 @@ def create_learning_interface():
|
|
647 |
margin: 1rem 0;
|
648 |
border-left: 4px solid #667eea;
|
649 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
"""
|
651 |
|
652 |
with gr.Blocks(css=custom_css, title="AI Learning Assistant v2.0") as interface:
|
@@ -657,34 +722,44 @@ def create_learning_interface():
|
|
657 |
<h1>π€ AI-Powered Personal Learning Assistant</h1>
|
658 |
<p><strong>Version 2.0</strong> - Clean Production Build</p>
|
659 |
<p>Multi-Agent Reasoning β’ Voice AI β’ Real-Time Data β’ ZeroGPU Optimized</p>
|
660 |
-
<p><em>Gradio Agents & MCP Hackathon 2025</em></p>
|
661 |
</div>
|
662 |
""")
|
663 |
|
664 |
# System Status
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
675 |
|
676 |
# Main Interface Tabs
|
677 |
with gr.Tabs():
|
678 |
|
679 |
# Tab 1: Smart Curriculum Generation
|
680 |
with gr.Tab("π Smart Curriculum"):
|
681 |
-
gr.HTML('<div class="feature-card"><h3>π§ AI-Powered Curriculum Generation</h3
|
682 |
|
683 |
with gr.Row():
|
684 |
with gr.Column():
|
685 |
subject_input = gr.Textbox(
|
686 |
label="π Subject/Topic",
|
687 |
-
placeholder="e.g., Python Programming, Data Science, Machine Learning"
|
|
|
688 |
)
|
689 |
level_input = gr.Dropdown(
|
690 |
choices=["beginner", "intermediate", "advanced"],
|
@@ -706,7 +781,7 @@ def create_learning_interface():
|
|
706 |
with gr.Column():
|
707 |
curriculum_output = gr.Markdown(
|
708 |
label="Generated Curriculum",
|
709 |
-
value="*Ready to generate personalized curriculum
|
710 |
)
|
711 |
|
712 |
# Event handler
|
@@ -725,13 +800,13 @@ def create_learning_interface():
|
|
725 |
outputs=[curriculum_output]
|
726 |
)
|
727 |
|
728 |
-
# Tab 2: Voice AI Learning
|
729 |
with gr.Tab("π€ Voice AI"):
|
730 |
-
gr.HTML('<div class="feature-card"><h3>π΅ Voice-Powered Learning with SambaNova</h3
|
731 |
|
732 |
with gr.Row():
|
733 |
with gr.Column():
|
734 |
-
#
|
735 |
audio_input = gr.Audio(
|
736 |
label="π€ Record Your Learning Request",
|
737 |
type="filepath"
|
@@ -756,10 +831,7 @@ def create_learning_interface():
|
|
756 |
|
757 |
**Instructions:**
|
758 |
1. Click the microphone to record your voice
|
759 |
-
2. Choose processing type
|
760 |
-
- **Learning Plan**: Generate curriculum from voice
|
761 |
-
- **Q&A Answer**: Get answers to spoken questions
|
762 |
-
- **Speech-to-Text**: Convert speech to text
|
763 |
3. Click "Process" to send to Qwen2-Audio-7B-Instruct
|
764 |
|
765 |
*Powered by SambaNova Cloud*"""
|
@@ -790,7 +862,7 @@ def create_learning_interface():
|
|
790 |
|
791 |
# Tab 3: User Profile
|
792 |
with gr.Tab("π€ Profile"):
|
793 |
-
gr.HTML('<div class="feature-card"><h3>π Create Your Learning Profile</h3
|
794 |
|
795 |
with gr.Row():
|
796 |
with gr.Column():
|
@@ -817,7 +889,7 @@ def create_learning_interface():
|
|
817 |
with gr.Column():
|
818 |
profile_output = gr.Markdown(
|
819 |
label="Profile Status",
|
820 |
-
value="*Ready to create your
|
821 |
)
|
822 |
|
823 |
create_profile_btn.click(
|
@@ -863,4 +935,4 @@ if __name__ == "__main__":
|
|
863 |
show_api=False,
|
864 |
server_name="0.0.0.0",
|
865 |
server_port=7860
|
866 |
-
)
|
|
|
1 |
#!/usr/bin/env python3
|
2 |
"""
|
3 |
+
AI-Powered Personal Learning Assistant
|
4 |
+
Version 2.0 - Clean Production Build for HuggingFace Spaces
|
5 |
Gradio Agents & MCP Hackathon 2025
|
6 |
|
7 |
Features:
|
8 |
- Multi-agent AI reasoning with smolagents
|
9 |
+
- Voice AI processing with SambaNova Cloud
|
10 |
- Real-time data integration via MCP
|
11 |
- ZeroGPU optimized for HuggingFace Spaces
|
12 |
"""
|
|
|
26 |
import gradio as gr
|
27 |
import requests
|
28 |
import plotly.graph_objects as go
|
29 |
+
import plotly.express as px
|
30 |
from dotenv import load_dotenv
|
31 |
|
32 |
+
# Audio processing
|
33 |
try:
|
34 |
import speech_recognition as sr
|
35 |
import pydub
|
|
|
39 |
AUDIO_AVAILABLE = False
|
40 |
print(f"β οΈ Audio libraries not available: {e}")
|
41 |
|
42 |
+
# AI and ML dependencies with graceful fallbacks
|
43 |
try:
|
44 |
import transformers
|
45 |
TRANSFORMERS_AVAILABLE = True
|
46 |
except ImportError:
|
47 |
TRANSFORMERS_AVAILABLE = False
|
48 |
+
print("β οΈ Transformers not available")
|
49 |
|
50 |
try:
|
51 |
import smolagents
|
|
|
55 |
SMOLAGENTS_AVAILABLE = False
|
56 |
print("β οΈ Smolagents not available - using fallback mode")
|
57 |
|
58 |
+
# Define tool decorator fallback BEFORE using it
|
59 |
+
if not SMOLAGENTS_AVAILABLE:
|
60 |
+
def tool(func):
|
61 |
+
"""Fallback tool decorator when smolagents is not available"""
|
62 |
+
func._is_tool = True
|
63 |
+
return func
|
64 |
+
else:
|
65 |
+
# Import tool from smolagents if available
|
66 |
+
pass # tool is already imported above
|
67 |
+
|
68 |
# HuggingFace Spaces support
|
69 |
try:
|
70 |
import spaces
|
71 |
SPACES_AVAILABLE = True
|
72 |
except ImportError:
|
73 |
SPACES_AVAILABLE = False
|
74 |
+
# Mock spaces decorator for local development
|
75 |
class spaces:
|
76 |
@staticmethod
|
77 |
def GPU(func):
|
|
|
82 |
logging.basicConfig(level=logging.INFO)
|
83 |
logger = logging.getLogger(__name__)
|
84 |
|
85 |
+
# Global configuration
|
86 |
SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY")
|
87 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
88 |
SAMBANOVA_AVAILABLE = bool(SAMBANOVA_API_KEY)
|
89 |
|
90 |
# ============================================================================
|
91 |
+
# Database Layer - Learning Progress Tracking
|
92 |
# ============================================================================
|
93 |
|
94 |
class LearningDatabase:
|
95 |
+
"""SQLite database for tracking learning progress and user profiles"""
|
96 |
|
97 |
def __init__(self, db_path: str = "learning_assistant.db"):
|
98 |
self.db_path = db_path
|
|
|
104 |
with sqlite3.connect(self.db_path) as conn:
|
105 |
cursor = conn.cursor()
|
106 |
|
107 |
+
# User profiles table
|
108 |
cursor.execute("""
|
109 |
CREATE TABLE IF NOT EXISTS user_profiles (
|
110 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
115 |
)
|
116 |
""")
|
117 |
|
118 |
+
# Learning sessions table
|
119 |
cursor.execute("""
|
120 |
CREATE TABLE IF NOT EXISTS learning_sessions (
|
121 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
129 |
)
|
130 |
""")
|
131 |
|
132 |
+
# Progress tracking table
|
133 |
+
cursor.execute("""
|
134 |
+
CREATE TABLE IF NOT EXISTS progress_tracking (
|
135 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
136 |
+
user_id INTEGER,
|
137 |
+
subject TEXT,
|
138 |
+
skill TEXT,
|
139 |
+
mastery_level REAL,
|
140 |
+
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
141 |
+
FOREIGN KEY (user_id) REFERENCES user_profiles (id)
|
142 |
+
)
|
143 |
+
""")
|
144 |
+
|
145 |
conn.commit()
|
146 |
logger.info("β
Database initialized successfully")
|
147 |
|
|
|
149 |
logger.error(f"β Database initialization failed: {e}")
|
150 |
|
151 |
# ============================================================================
|
152 |
+
# Multi-Agent AI System with Smolagents
|
153 |
# ============================================================================
|
154 |
|
155 |
class LearningAgents:
|
|
|
167 |
return
|
168 |
|
169 |
try:
|
170 |
+
# Initialize smolagents with proper configuration
|
171 |
+
from smolagents import HfApiModel
|
172 |
+
|
173 |
+
# Use HuggingFace models for reasoning
|
174 |
+
model = HfApiModel("microsoft/DialoGPT-medium")
|
175 |
|
176 |
# Create specialized agents
|
177 |
+
self.curriculum_agent = self.create_curriculum_agent(model)
|
178 |
+
self.content_agent = self.create_content_agent(model)
|
179 |
+
self.assessment_agent = self.create_assessment_agent(model)
|
180 |
+
|
181 |
+
logger.info("β
Smolagents multi-agent system initialized")
|
182 |
+
|
183 |
+
except Exception as e:
|
184 |
+
logger.error(f"β Smolagents setup failed: {e}")
|
185 |
+
self.agents_available = False
|
186 |
+
self.setup_fallback_agents()
|
187 |
+
|
188 |
+
def create_curriculum_agent(self, model):
|
189 |
+
"""Create curriculum planning agent with smolagents"""
|
190 |
+
if not self.agents_available:
|
191 |
+
return self.create_fallback_agent("curriculum")
|
192 |
+
|
193 |
+
try:
|
194 |
+
agent = CodeAgent(
|
195 |
tools=[self.curriculum_planning_tool],
|
196 |
model=model,
|
197 |
max_iterations=3
|
198 |
)
|
199 |
+
return agent
|
200 |
+
except Exception as e:
|
201 |
+
logger.error(f"Curriculum agent creation failed: {e}")
|
202 |
+
return self.create_fallback_agent("curriculum")
|
203 |
+
|
204 |
+
def create_content_agent(self, model):
|
205 |
+
"""Create content generation agent with smolagents"""
|
206 |
+
if not self.agents_available:
|
207 |
+
return self.create_fallback_agent("content")
|
208 |
+
|
209 |
+
try:
|
210 |
+
agent = ReactCodeAgent(
|
211 |
tools=[self.content_generation_tool],
|
212 |
model=model,
|
213 |
max_iterations=2
|
214 |
)
|
215 |
+
return agent
|
|
|
|
|
216 |
except Exception as e:
|
217 |
+
logger.error(f"Content agent creation failed: {e}")
|
218 |
+
return self.create_fallback_agent("content")
|
219 |
+
|
220 |
+
def create_assessment_agent(self, model):
|
221 |
+
"""Create assessment agent with smolagents"""
|
222 |
+
if not self.agents_available:
|
223 |
+
return self.create_fallback_agent("assessment")
|
224 |
+
|
225 |
+
try:
|
226 |
+
agent = CodeAgent(
|
227 |
+
tools=[self.assessment_generation_tool],
|
228 |
+
model=model,
|
229 |
+
max_iterations=2
|
230 |
+
)
|
231 |
+
return agent
|
232 |
+
except Exception as e:
|
233 |
+
logger.error(f"Assessment agent creation failed: {e}")
|
234 |
+
return self.create_fallback_agent("assessment")
|
235 |
|
236 |
def setup_fallback_agents(self):
|
237 |
"""Setup fallback agents when smolagents is not available"""
|
238 |
self.curriculum_agent = self.create_fallback_agent("curriculum")
|
239 |
self.content_agent = self.create_fallback_agent("content")
|
240 |
+
self.assessment_agent = self.create_fallback_agent("assessment")
|
241 |
|
242 |
def create_fallback_agent(self, agent_type: str):
|
243 |
"""Create fallback agent for when smolagents is unavailable"""
|
|
|
246 |
self.agent_type = agent_type
|
247 |
|
248 |
def run(self, prompt):
|
249 |
+
return f"π **Fallback {self.agent_type.title()} Agent**\n\n{self.generate_fallback_response(prompt)}"
|
250 |
+
|
251 |
+
def generate_fallback_response(self, prompt):
|
252 |
if self.agent_type == "curriculum":
|
253 |
return self.generate_curriculum_fallback(prompt)
|
254 |
elif self.agent_type == "content":
|
255 |
return self.generate_content_fallback(prompt)
|
256 |
+
elif self.agent_type == "assessment":
|
257 |
+
return self.generate_assessment_fallback(prompt)
|
258 |
else:
|
259 |
+
return "This feature requires smolagents. Please install with: pip install smolagents"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
|
261 |
return FallbackAgent(agent_type)
|
262 |
|
263 |
+
# Tool methods - decorated only when smolagents is available
|
|
|
264 |
def curriculum_planning_tool(self, subject: str, level: str, goals: str) -> str:
|
265 |
+
"""Curriculum planning tool for smolagents"""
|
266 |
return f"""
|
267 |
# π AI-Generated Curriculum: {subject}
|
268 |
|
269 |
## π― Learning Path for {level.title()} Level
|
270 |
|
271 |
+
### Phase 1: Foundation Building
|
272 |
+
- Core concepts and terminology
|
|
|
|
|
273 |
- Essential prerequisites review
|
274 |
- Hands-on introduction exercises
|
|
|
275 |
|
276 |
+
### Phase 2: Skill Development
|
277 |
- Practical application projects
|
278 |
- Guided practice sessions
|
279 |
+
- Real-world case studies
|
|
|
280 |
|
281 |
+
### Phase 3: Advanced Application
|
282 |
- Complex problem solving
|
283 |
- Integration with other topics
|
284 |
- Portfolio development
|
|
|
285 |
|
286 |
### π Progress Milestones
|
287 |
+
1. **Week 1-2**: Foundation mastery
|
288 |
+
2. **Week 3-4**: Practical application
|
289 |
+
3. **Week 5-6**: Advanced projects
|
|
|
|
|
|
|
|
|
|
|
290 |
|
291 |
+
**Personalized for:** {goals}
|
292 |
"""
|
293 |
|
|
|
294 |
def content_generation_tool(self, topic: str, difficulty: str) -> str:
|
295 |
"""Content generation tool for smolagents"""
|
296 |
return f"""
|
297 |
# π Learning Content: {topic}
|
298 |
|
299 |
+
## π Overview
|
300 |
+
This {difficulty}-level content covers essential concepts in {topic}.
|
301 |
|
302 |
## π― Key Learning Objectives
|
303 |
+
- Understand fundamental principles
|
304 |
+
- Apply concepts to real scenarios
|
305 |
+
- Develop practical skills
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
|
307 |
+
## π Content Structure
|
308 |
+
1. **Introduction & Context**
|
309 |
+
2. **Core Concepts**
|
310 |
+
3. **Practical Examples**
|
311 |
+
4. **Hands-on Exercises**
|
312 |
+
5. **Assessment & Review**
|
313 |
|
314 |
## π Next Steps
|
315 |
+
Continue with advanced topics or apply skills in projects.
|
|
|
|
|
|
|
|
|
316 |
"""
|
317 |
+
|
318 |
+
def assessment_generation_tool(self, topic: str, num_questions: int = 5) -> Dict:
|
319 |
+
"""Assessment generation tool for smolagents"""
|
320 |
+
return {
|
321 |
+
"quiz_title": f"{topic} Assessment",
|
322 |
+
"questions": [
|
323 |
+
{
|
324 |
+
"question": f"What is the main concept of {topic}?",
|
325 |
+
"options": ["Option A", "Option B", "Option C", "Option D"],
|
326 |
+
"correct": 0
|
327 |
+
} for i in range(num_questions)
|
328 |
+
],
|
329 |
+
"difficulty": "intermediate",
|
330 |
+
"estimated_time": f"{num_questions * 2} minutes"
|
331 |
+
}
|
332 |
+
|
333 |
+
# Apply @tool decorator if smolagents is available
|
334 |
+
if SMOLAGENTS_AVAILABLE:
|
335 |
+
LearningAgents.curriculum_planning_tool = tool(LearningAgents.curriculum_planning_tool)
|
336 |
+
LearningAgents.content_generation_tool = tool(LearningAgents.content_generation_tool)
|
337 |
+
LearningAgents.assessment_generation_tool = tool(LearningAgents.assessment_generation_tool)
|
338 |
|
339 |
# ============================================================================
|
340 |
# SambaNova Audio AI Integration
|
|
|
356 |
if not self.available:
|
357 |
return {
|
358 |
"error": "SambaNova Audio AI not available",
|
359 |
+
"message": "Please set SAMBANOVA_API_KEY environment variable"
|
360 |
}
|
361 |
|
362 |
try:
|
363 |
+
# Convert audio to required format
|
364 |
audio_data = self.prepare_audio(audio_path)
|
365 |
|
366 |
+
# Prepare request for SambaNova API
|
367 |
headers = {
|
368 |
"Authorization": f"Bearer {self.api_key}",
|
369 |
"Content-Type": "application/json"
|
|
|
375 |
{
|
376 |
"role": "user",
|
377 |
"content": [
|
378 |
+
{"type": "text", "text": prompt or "Analyze this audio and provide educational insights"},
|
379 |
{"type": "audio", "audio": audio_data}
|
380 |
]
|
381 |
}
|
|
|
409 |
def prepare_audio(self, audio_path: str) -> str:
|
410 |
"""Prepare audio for SambaNova API"""
|
411 |
try:
|
412 |
+
# Convert to WAV format if needed
|
413 |
if not audio_path.endswith('.wav'):
|
414 |
audio = pydub.AudioSegment.from_file(audio_path)
|
415 |
wav_path = audio_path.replace(Path(audio_path).suffix, '.wav')
|
416 |
audio.export(wav_path, format="wav")
|
417 |
audio_path = wav_path
|
418 |
|
419 |
+
# Read and encode audio
|
420 |
import base64
|
421 |
with open(audio_path, 'rb') as f:
|
422 |
audio_data = base64.b64encode(f.read()).decode('utf-8')
|
|
|
430 |
def generate_learning_plan_from_audio(self, audio_path: str) -> str:
|
431 |
"""Generate learning plan from audio input"""
|
432 |
prompt = """
|
433 |
+
Listen to this audio and create a comprehensive learning plan.
|
434 |
+
Include:
|
435 |
1. Identified learning goals from the audio
|
436 |
+
2. Recommended curriculum structure
|
437 |
3. Timeline and milestones
|
438 |
4. Resources and next steps
|
439 |
"""
|
|
|
460 |
"""Answer questions from audio input"""
|
461 |
prompt = """
|
462 |
Listen to this audio question and provide a comprehensive educational answer.
|
463 |
+
Structure your response with:
|
464 |
1. Clear explanation of the concept
|
465 |
2. Practical examples
|
466 |
3. Additional learning resources
|
|
|
488 |
def convert_speech_to_text(self, audio_path: str) -> str:
|
489 |
"""Convert speech to text using local speech recognition"""
|
490 |
if not AUDIO_AVAILABLE:
|
491 |
+
return "β Speech recognition not available"
|
492 |
|
493 |
try:
|
494 |
recognizer = sr.Recognizer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
495 |
with sr.AudioFile(audio_path) as source:
|
496 |
audio_data = recognizer.record(source)
|
497 |
text = recognizer.recognize_google(audio_data)
|
498 |
+
return f"**Transcribed Text**: {text}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
499 |
except Exception as e:
|
500 |
return f"β **Speech Recognition Error**: {e}"
|
501 |
|
502 |
# ============================================================================
|
503 |
+
# Main Learning Assistant Class
|
504 |
# ============================================================================
|
505 |
|
506 |
class LearningAssistant:
|
|
|
519 |
if self.agents.agents_available:
|
520 |
# Use smolagents for advanced reasoning
|
521 |
prompt = f"""
|
522 |
+
Create a comprehensive curriculum for:
|
523 |
Subject: {subject}
|
524 |
Level: {level}
|
525 |
Goals: {goals}
|
|
|
530 |
return result
|
531 |
else:
|
532 |
# Fallback curriculum generation
|
533 |
+
return self.generate_fallback_curriculum(subject, level, goals)
|
534 |
|
535 |
except Exception as e:
|
536 |
logger.error(f"Curriculum generation error: {e}")
|
537 |
+
return f"β **Error**: {e}\n\nPlease try again or use the fallback interface."
|
538 |
+
|
539 |
+
def generate_fallback_curriculum(self, subject: str, level: str, goals: str) -> str:
|
540 |
+
"""Fallback curriculum generation when agents are unavailable"""
|
541 |
+
return f"""
|
542 |
+
# π Learning Curriculum: {subject}
|
543 |
+
|
544 |
+
## π― Customized for {level.title()} Level
|
545 |
+
|
546 |
+
### π Learning Goals
|
547 |
+
{goals}
|
548 |
+
|
549 |
+
### ποΈ Structured Learning Path
|
550 |
+
|
551 |
+
#### Phase 1: Foundation (Weeks 1-2)
|
552 |
+
- **Core Concepts**: Introduction to {subject} fundamentals
|
553 |
+
- **Prerequisites**: Review essential background knowledge
|
554 |
+
- **Initial Projects**: Hands-on practice exercises
|
555 |
+
|
556 |
+
#### Phase 2: Development (Weeks 3-4)
|
557 |
+
- **Skill Building**: Intermediate concepts and techniques
|
558 |
+
- **Practical Applications**: Real-world project work
|
559 |
+
- **Problem Solving**: Guided challenges and exercises
|
560 |
+
|
561 |
+
#### Phase 3: Mastery (Weeks 5-6)
|
562 |
+
- **Advanced Topics**: Complex applications and integrations
|
563 |
+
- **Portfolio Development**: Showcase projects
|
564 |
+
- **Knowledge Integration**: Connecting concepts across domains
|
565 |
+
|
566 |
+
### π Progress Tracking
|
567 |
+
- **Weekly Assessments**: Track understanding and skill development
|
568 |
+
- **Milestone Projects**: Demonstrate cumulative learning
|
569 |
+
- **Peer Reviews**: Collaborative learning opportunities
|
570 |
+
|
571 |
+
### π Recommended Resources
|
572 |
+
- Online courses and tutorials
|
573 |
+
- Practice platforms and tools
|
574 |
+
- Community forums and support groups
|
575 |
+
|
576 |
+
### π― Next Steps
|
577 |
+
Continue to advanced topics or apply skills in specialized areas.
|
578 |
+
|
579 |
+
---
|
580 |
+
*Generated by AI Learning Assistant - Fallback Mode*
|
581 |
+
"""
|
582 |
|
583 |
def process_audio_learning_request(self, audio_input) -> str:
|
584 |
"""Process audio input for learning plan generation"""
|
|
|
586 |
return "β **Error**: No audio provided"
|
587 |
|
588 |
try:
|
589 |
+
# Save audio from Gradio input
|
590 |
audio_path = self.save_gradio_audio(audio_input)
|
591 |
+
|
592 |
+
# Process with SambaNova
|
593 |
result = self.audio_ai.generate_learning_plan_from_audio(audio_path)
|
594 |
+
|
595 |
+
# Cleanup temp file
|
596 |
self.cleanup_temp_file(audio_path)
|
597 |
+
|
598 |
return result
|
599 |
|
600 |
except Exception as e:
|
|
|
635 |
"""Save Gradio audio input to temporary file"""
|
636 |
try:
|
637 |
if isinstance(audio_input, str):
|
638 |
+
# Already a file path
|
639 |
return audio_input
|
640 |
elif hasattr(audio_input, 'name'):
|
641 |
+
# File object
|
642 |
return audio_input.name
|
643 |
else:
|
644 |
+
# Handle other audio input types
|
645 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.wav')
|
646 |
temp_file.write(audio_input)
|
647 |
temp_file.close()
|
|
|
684 |
# Initialize learning assistant
|
685 |
learning_assistant = LearningAssistant()
|
686 |
|
687 |
+
# Custom CSS for better styling
|
688 |
custom_css = """
|
689 |
.gradio-container {
|
690 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
691 |
}
|
692 |
.main-header {
|
693 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
704 |
margin: 1rem 0;
|
705 |
border-left: 4px solid #667eea;
|
706 |
}
|
707 |
+
.status-indicator {
|
708 |
+
padding: 0.5rem;
|
709 |
+
border-radius: 5px;
|
710 |
+
margin: 0.5rem 0;
|
711 |
+
}
|
712 |
+
.status-success { background: #d4edda; color: #155724; }
|
713 |
+
.status-warning { background: #fff3cd; color: #856404; }
|
714 |
+
.status-error { background: #f8d7da; color: #721c24; }
|
715 |
"""
|
716 |
|
717 |
with gr.Blocks(css=custom_css, title="AI Learning Assistant v2.0") as interface:
|
|
|
722 |
<h1>π€ AI-Powered Personal Learning Assistant</h1>
|
723 |
<p><strong>Version 2.0</strong> - Clean Production Build</p>
|
724 |
<p>Multi-Agent Reasoning β’ Voice AI β’ Real-Time Data β’ ZeroGPU Optimized</p>
|
|
|
725 |
</div>
|
726 |
""")
|
727 |
|
728 |
# System Status
|
729 |
+
with gr.Row():
|
730 |
+
with gr.Column():
|
731 |
+
status_html = f"""
|
732 |
+
<div class="feature-card">
|
733 |
+
<h3>π§ System Status</h3>
|
734 |
+
<div class="status-indicator {'status-success' if SMOLAGENTS_AVAILABLE else 'status-warning'}">
|
735 |
+
π§ <strong>Smolagents</strong>: {'Available' if SMOLAGENTS_AVAILABLE else 'Fallback Mode'}
|
736 |
+
</div>
|
737 |
+
<div class="status-indicator {'status-success' if SAMBANOVA_AVAILABLE else 'status-warning'}">
|
738 |
+
π€ <strong>SambaNova Audio AI</strong>: {'Available' if SAMBANOVA_AVAILABLE else 'Not Configured'}
|
739 |
+
</div>
|
740 |
+
<div class="status-indicator {'status-success' if AUDIO_AVAILABLE else 'status-warning'}">
|
741 |
+
π <strong>Audio Processing</strong>: {'Available' if AUDIO_AVAILABLE else 'Limited'}
|
742 |
+
</div>
|
743 |
+
<div class="status-indicator {'status-success' if SPACES_AVAILABLE else 'status-warning'}">
|
744 |
+
βοΈ <strong>HuggingFace Spaces</strong>: {'Available' if SPACES_AVAILABLE else 'Local Mode'}
|
745 |
+
</div>
|
746 |
+
</div>
|
747 |
+
"""
|
748 |
+
gr.HTML(status_html)
|
749 |
|
750 |
# Main Interface Tabs
|
751 |
with gr.Tabs():
|
752 |
|
753 |
# Tab 1: Smart Curriculum Generation
|
754 |
with gr.Tab("π Smart Curriculum"):
|
755 |
+
gr.HTML('<div class="feature-card"><h3>π§ AI-Powered Curriculum Generation</h3></div>')
|
756 |
|
757 |
with gr.Row():
|
758 |
with gr.Column():
|
759 |
subject_input = gr.Textbox(
|
760 |
label="π Subject/Topic",
|
761 |
+
placeholder="e.g., Python Programming, Data Science, Machine Learning",
|
762 |
+
lines=1
|
763 |
)
|
764 |
level_input = gr.Dropdown(
|
765 |
choices=["beginner", "intermediate", "advanced"],
|
|
|
781 |
with gr.Column():
|
782 |
curriculum_output = gr.Markdown(
|
783 |
label="Generated Curriculum",
|
784 |
+
value="*Ready to generate personalized curriculum...*"
|
785 |
)
|
786 |
|
787 |
# Event handler
|
|
|
800 |
outputs=[curriculum_output]
|
801 |
)
|
802 |
|
803 |
+
# Tab 2: Voice AI Learning
|
804 |
with gr.Tab("π€ Voice AI"):
|
805 |
+
gr.HTML('<div class="feature-card"><h3>π΅ Voice-Powered Learning with SambaNova</h3></div>')
|
806 |
|
807 |
with gr.Row():
|
808 |
with gr.Column():
|
809 |
+
# Clean Audio component - NO deprecated parameters
|
810 |
audio_input = gr.Audio(
|
811 |
label="π€ Record Your Learning Request",
|
812 |
type="filepath"
|
|
|
831 |
|
832 |
**Instructions:**
|
833 |
1. Click the microphone to record your voice
|
834 |
+
2. Choose processing type (Learning Plan, Q&A, or Speech-to-Text)
|
|
|
|
|
|
|
835 |
3. Click "Process" to send to Qwen2-Audio-7B-Instruct
|
836 |
|
837 |
*Powered by SambaNova Cloud*"""
|
|
|
862 |
|
863 |
# Tab 3: User Profile
|
864 |
with gr.Tab("π€ Profile"):
|
865 |
+
gr.HTML('<div class="feature-card"><h3>π Create Your Learning Profile</h3></div>')
|
866 |
|
867 |
with gr.Row():
|
868 |
with gr.Column():
|
|
|
889 |
with gr.Column():
|
890 |
profile_output = gr.Markdown(
|
891 |
label="Profile Status",
|
892 |
+
value="*Ready to create your learning profile...*"
|
893 |
)
|
894 |
|
895 |
create_profile_btn.click(
|
|
|
935 |
show_api=False,
|
936 |
server_name="0.0.0.0",
|
937 |
server_port=7860
|
938 |
+
)
|
requirements.txt
CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
|
|