mihirinamdar commited on
Commit
30fae6f
Β·
1 Parent(s): c4cb380

FINAL FIX: @tool decorator error resolved + optimized deps

Browse files
Files changed (2) hide show
  1. app.py +252 -180
  2. requirements.txt +0 -0
app.py CHANGED
@@ -1,12 +1,12 @@
1
  #!/usr/bin/env python3
2
  """
3
- AI-Powered Personal Learning Assistant v2.0
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 with graceful fallback
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
- # Configuration
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 tracking"""
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 model for smolagents
143
- if HF_TOKEN:
144
- model = HfApiModel("microsoft/DialoGPT-medium", token=HF_TOKEN)
145
- else:
146
- model = HfApiModel("microsoft/DialoGPT-medium")
147
 
148
  # Create specialized agents
149
- self.curriculum_agent = CodeAgent(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  tools=[self.curriculum_planning_tool],
151
  model=model,
152
  max_iterations=3
153
  )
154
-
155
- self.content_agent = ReactCodeAgent(
 
 
 
 
 
 
 
 
 
 
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"❌ Smolagents setup failed: {e}")
165
- self.agents_available = False
166
- self.setup_fallback_agents()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 "Feature requires smolagents. Using fallback mode."
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
- # Smolagents tools (properly decorated)
241
- @tool
242
  def curriculum_planning_tool(self, subject: str, level: str, goals: str) -> str:
243
- """Advanced curriculum planning tool for smolagents"""
244
  return f"""
245
  # πŸ“š AI-Generated Curriculum: {subject}
246
 
247
  ## 🎯 Learning Path for {level.title()} Level
248
 
249
- ### Customized for Goals: {goals}
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 (Weeks 3-4)
258
  - Practical application projects
259
  - Guided practice sessions
260
- - Real-world case studies in {subject}
261
- - Intermediate challenges
262
 
263
- ### Phase 3: Advanced Application (Weeks 5-6)
264
  - Complex problem solving
265
  - Integration with other topics
266
  - Portfolio development
267
- - Mastery demonstrations
268
 
269
  ### πŸ“ˆ Progress Milestones
270
- 1. **Foundation Check**: Week 2 assessment
271
- 2. **Skill Validation**: Week 4 project review
272
- 3. **Mastery Demo**: Week 6 final portfolio
273
-
274
- ### πŸ”— Recommended Next Steps
275
- - Advanced {subject} topics
276
- - Related field exploration
277
- - Professional application
278
 
279
- *Generated by Smolagents Multi-Agent System*
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 ({difficulty.title()} Level)
289
- Comprehensive educational content covering {topic} at {difficulty} level.
290
 
291
  ## 🎯 Key Learning Objectives
292
- - Master core concepts in {topic}
293
- - Apply knowledge to practical scenarios
294
- - Develop transferable skills
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
- ### 5. Assessment & Review
312
- Check your understanding and identify areas for improvement.
 
 
 
 
313
 
314
  ## πŸš€ Next Steps
315
- - Practice with additional exercises
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 configure SAMBANOVA_API_KEY"
343
  }
344
 
345
  try:
346
- # Prepare audio data
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 for educational insights"},
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
- # Encode to base64
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
- Analyze this audio and create a comprehensive learning plan. Include:
 
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
- Include:
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 libraries not available"
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.agents.curriculum_agent.run(f"Generate curriculum for {subject} at {level} level with goals: {goals}")
530
 
531
  except Exception as e:
532
  logger.error(f"Curriculum generation error: {e}")
533
- return f"❌ **Error**: {e}\n\nTrying fallback mode..."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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', system-ui, sans-serif;
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
- status_html = f"""
666
- <div class="feature-card">
667
- <h3>πŸ”§ System Status</h3>
668
- <p>🧠 <strong>Smolagents</strong>: {'βœ… Available' if SMOLAGENTS_AVAILABLE else '⚠️ Fallback Mode'}</p>
669
- <p>🎀 <strong>SambaNova Audio AI</strong>: {'βœ… Available' if SAMBANOVA_AVAILABLE else '⚠️ Not Configured'}</p>
670
- <p>πŸ”Š <strong>Audio Processing</strong>: {'βœ… Available' if AUDIO_AVAILABLE else '⚠️ Limited'}</p>
671
- <p>☁️ <strong>HuggingFace Spaces</strong>: {'βœ… Available' if SPACES_AVAILABLE else '⚠️ Local Mode'}</p>
672
- </div>
673
- """
674
- gr.HTML(status_html)
 
 
 
 
 
 
 
 
 
 
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><p>Generate personalized learning paths using multi-agent AI reasoning</p></div>')
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 with multi-agent AI reasoning...*"
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><p>Use Qwen2-Audio-7B-Instruct for voice-based learning interactions</p></div>')
731
 
732
  with gr.Row():
733
  with gr.Column():
734
- # CLEAN Audio component - NO deprecated parameters
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><p>Personalize your learning experience</p></div>')
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 personalized learning profile...*"
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