Meet Patel commited on
Commit
bc987d8
·
1 Parent(s): 250bf8c

Implement AI tutoring and content generation tools for TutorX

Browse files

- Added ai_tutor_tools.py for contextualized AI tutoring features, including session management, interaction logging, and personalized responses.
- Introduced content_generation_tools.py for automated content creation, including interactive exercises, scenario-based learning, and gamified content.
- Developed test_ai_integration.py to validate the functionality of AI tutoring and content generation features through comprehensive test cases.

README.md CHANGED
@@ -18,6 +18,20 @@ A comprehensive Model Context Protocol (MCP) server for educational AI tutoring
18
 
19
  TutorX-MCP is an adaptive, multi-modal, and collaborative AI tutoring platform that leverages the Model Context Protocol (MCP) for tool integration and Gradio for user-friendly interfaces. It provides a range of educational features accessible via both MCP clients and a dedicated web interface.
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  ![TutorX-MCP](https://via.placeholder.com/800x400?text=TutorX-MCP+Educational+Platform)
22
 
23
  For a comprehensive analysis of the project from architectural, development, and product perspectives, please see our [Project Analysis Document](PROJECT_ANALYSIS.md).
@@ -167,6 +181,23 @@ The server exposes the following MCP tools and resources:
167
  - **Learning Path Tools** (learning_path_tools.py)
168
  - `get_learning_path`: Generate personalized learning paths based on student level and target concepts
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  - **Memory Tools** (v0.2.0)
171
  - `read_memory_tool`: Retrieve stored context from the Memory Bank
172
  - `write_memory_tool`: Store new contextual information in the Memory Bank
@@ -201,7 +232,9 @@ tutorx-mcp/
201
  │ │ ├── lesson_tools.py # Lesson generation tools
202
  │ │ ├── ocr_tools.py # Document OCR tools
203
  │ │ ├── interaction_tools.py # Student interaction tools
204
- │ │ └── learning_path_tools.py # Learning path tools
 
 
205
  │ └── prompts/ # LLM prompt templates
206
  ├── tests/ # Test suite
207
  │ ├── test_mcp_server.py # MCP server tests
@@ -275,6 +308,7 @@ python run_tests.py
275
  ## Documentation
276
 
277
  - [Project Analysis](PROJECT_ANALYSIS.md): Comprehensive analysis of architecture, implementation, and product features
 
278
  - [MCP Protocol](docs/mcp.md): Details about the Model Context Protocol
279
  - [Product Requirements](docs/prd.md): Original requirements document
280
  - [SDK Documentation](docs/sdk.md): Client SDK usage
 
18
 
19
  TutorX-MCP is an adaptive, multi-modal, and collaborative AI tutoring platform that leverages the Model Context Protocol (MCP) for tool integration and Gradio for user-friendly interfaces. It provides a range of educational features accessible via both MCP clients and a dedicated web interface.
20
 
21
+ ## ✨ New: Enhanced AI Integration & Capabilities
22
+
23
+ **🤖 Contextualized AI Tutoring:**
24
+ - **Session-based tutoring** with persistent context and memory
25
+ - **Step-by-step guidance** that breaks complex concepts into manageable steps
26
+ - **Alternative explanations** using multiple approaches (visual, analogy, real-world)
27
+ - **Adaptive responses** that adjust to student understanding levels
28
+
29
+ **🎨 Advanced Automated Content Generation:**
30
+ - **Interactive exercises** with multiple components and adaptive features
31
+ - **Scenario-based learning** with realistic contexts and decision points
32
+ - **Gamified content** with game mechanics and progressive difficulty
33
+ - **Multi-modal content** supporting different learning styles
34
+
35
  ![TutorX-MCP](https://via.placeholder.com/800x400?text=TutorX-MCP+Educational+Platform)
36
 
37
  For a comprehensive analysis of the project from architectural, development, and product perspectives, please see our [Project Analysis Document](PROJECT_ANALYSIS.md).
 
181
  - **Learning Path Tools** (learning_path_tools.py)
182
  - `get_learning_path`: Generate personalized learning paths based on student level and target concepts
183
 
184
+ - **AI Tutoring Tools** (ai_tutor_tools.py) ✨ **NEW**
185
+ - `start_tutoring_session`: Start contextualized AI tutoring sessions with memory
186
+ - `ai_tutor_chat`: Interactive chat with AI tutor providing personalized responses
187
+ - `get_step_by_step_guidance`: Break down complex concepts into manageable steps
188
+ - `get_alternative_explanations`: Multiple explanation approaches for different learning styles
189
+ - `update_student_understanding`: Track and adapt to student understanding levels
190
+ - `end_tutoring_session`: Generate comprehensive session summaries
191
+
192
+ - **Content Generation Tools** (content_generation_tools.py) ✨ **NEW**
193
+ - `generate_interactive_exercise`: Create engaging interactive exercises with multiple components
194
+ - `generate_adaptive_content_sequence`: Build adaptive content that adjusts to student performance
195
+ - `generate_scenario_based_learning`: Create realistic scenario-based learning experiences
196
+ - `generate_multimodal_content`: Generate content for different learning modalities
197
+ - `generate_adaptive_assessment`: Create assessments that adapt based on student responses
198
+ - `generate_gamified_content`: Generate game-based learning content with mechanics
199
+ - `validate_generated_content`: Quality-check and validate educational content
200
+
201
  - **Memory Tools** (v0.2.0)
202
  - `read_memory_tool`: Retrieve stored context from the Memory Bank
203
  - `write_memory_tool`: Store new contextual information in the Memory Bank
 
232
  │ │ ├── lesson_tools.py # Lesson generation tools
233
  │ │ ├── ocr_tools.py # Document OCR tools
234
  │ │ ├── interaction_tools.py # Student interaction tools
235
+ │ │ ├── learning_path_tools.py # Learning path tools
236
+ │ │ ├── ai_tutor_tools.py # ✨ Contextualized AI tutoring
237
+ │ │ └── content_generation_tools.py # ✨ Advanced content generation
238
  │ └── prompts/ # LLM prompt templates
239
  ├── tests/ # Test suite
240
  │ ├── test_mcp_server.py # MCP server tests
 
308
  ## Documentation
309
 
310
  - [Project Analysis](PROJECT_ANALYSIS.md): Comprehensive analysis of architecture, implementation, and product features
311
+ - [AI Integration Features](docs/AI_INTEGRATION_FEATURES.md): ✨ **NEW** - Detailed guide to contextualized AI tutoring and content generation
312
  - [MCP Protocol](docs/mcp.md): Details about the Model Context Protocol
313
  - [Product Requirements](docs/prd.md): Original requirements document
314
  - [SDK Documentation](docs/sdk.md): Client SDK usage
app.py CHANGED
@@ -493,6 +493,64 @@ def sync_get_progress_summary(student_id, days=7):
493
  except Exception as e:
494
  return {"error": str(e)}
495
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  # Define async functions outside the interface
497
  async def on_generate_quiz(concept, difficulty):
498
  try:
@@ -728,6 +786,120 @@ async def document_ocr_async(file):
728
  except Exception as e:
729
  return {"error": f"Error processing document: {str(e)}", "success": False}
730
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
731
  # Create Gradio interface
732
  def create_gradio_interface():
733
  # Set a default student ID for the demo
@@ -1093,9 +1265,225 @@ def create_gradio_interface():
1093
  inputs=[doc_input],
1094
  outputs=[doc_output]
1095
  )
1096
-
1097
- # Tab 4: Adaptive Learning
1098
- with gr.Tab("4 🧠 Adaptive Learning", elem_id="adaptive_learning_tab"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1099
  gr.Markdown("## Adaptive Learning System")
1100
  gr.Markdown("Experience personalized learning with real-time adaptation based on your performance.")
1101
 
@@ -1264,8 +1652,8 @@ def create_gradio_interface():
1264
  - **Engagement Metrics**: Measures learning engagement
1265
  """)
1266
 
1267
- # Tab 5: Data Analytics
1268
- with gr.Tab("5 Data Analytics", elem_id="data_analytics_tab"):
1269
  gr.Markdown("## Plagiarism Detection")
1270
 
1271
  with gr.Row():
 
493
  except Exception as e:
494
  return {"error": str(e)}
495
 
496
+ # AI Tutoring synchronous wrappers
497
+ def sync_start_tutoring_session(student_id, subject, learning_objectives):
498
+ """Synchronous wrapper for start_tutoring_session_async"""
499
+ try:
500
+ return asyncio.run(start_tutoring_session_async(student_id, subject, learning_objectives))
501
+ except Exception as e:
502
+ return {"error": str(e)}
503
+
504
+ def sync_ai_tutor_chat(session_id, student_query, request_type):
505
+ """Synchronous wrapper for ai_tutor_chat_async"""
506
+ try:
507
+ return asyncio.run(ai_tutor_chat_async(session_id, student_query, request_type))
508
+ except Exception as e:
509
+ return {"error": str(e)}
510
+
511
+ def sync_get_step_by_step_guidance(session_id, concept, current_step):
512
+ """Synchronous wrapper for get_step_by_step_guidance_async"""
513
+ try:
514
+ return asyncio.run(get_step_by_step_guidance_async(session_id, concept, current_step))
515
+ except Exception as e:
516
+ return {"error": str(e)}
517
+
518
+ def sync_get_alternative_explanations(session_id, concept, explanation_types):
519
+ """Synchronous wrapper for get_alternative_explanations_async"""
520
+ try:
521
+ return asyncio.run(get_alternative_explanations_async(session_id, concept, explanation_types))
522
+ except Exception as e:
523
+ return {"error": str(e)}
524
+
525
+ def sync_end_tutoring_session(session_id, session_summary):
526
+ """Synchronous wrapper for end_tutoring_session_async"""
527
+ try:
528
+ return asyncio.run(end_tutoring_session_async(session_id, session_summary))
529
+ except Exception as e:
530
+ return {"error": str(e)}
531
+
532
+ # Content Generation synchronous wrappers
533
+ def sync_generate_interactive_exercise(concept, exercise_type, difficulty_level, student_level):
534
+ """Synchronous wrapper for generate_interactive_exercise_async"""
535
+ try:
536
+ return asyncio.run(generate_interactive_exercise_async(concept, exercise_type, difficulty_level, student_level))
537
+ except Exception as e:
538
+ return {"error": str(e)}
539
+
540
+ def sync_generate_scenario_based_learning(concept, scenario_type, complexity_level):
541
+ """Synchronous wrapper for generate_scenario_based_learning_async"""
542
+ try:
543
+ return asyncio.run(generate_scenario_based_learning_async(concept, scenario_type, complexity_level))
544
+ except Exception as e:
545
+ return {"error": str(e)}
546
+
547
+ def sync_generate_gamified_content(concept, game_type, target_age_group):
548
+ """Synchronous wrapper for generate_gamified_content_async"""
549
+ try:
550
+ return asyncio.run(generate_gamified_content_async(concept, game_type, target_age_group))
551
+ except Exception as e:
552
+ return {"error": str(e)}
553
+
554
  # Define async functions outside the interface
555
  async def on_generate_quiz(concept, difficulty):
556
  try:
 
786
  except Exception as e:
787
  return {"error": f"Error processing document: {str(e)}", "success": False}
788
 
789
+ # AI Tutoring async functions
790
+ async def start_tutoring_session_async(student_id, subject, learning_objectives):
791
+ try:
792
+ async with sse_client(SERVER_URL) as (sse, write):
793
+ async with ClientSession(sse, write) as session:
794
+ await session.initialize()
795
+ response = await session.call_tool("start_tutoring_session", {
796
+ "student_id": student_id,
797
+ "subject": subject,
798
+ "learning_objectives": learning_objectives
799
+ })
800
+ return await extract_response_content(response)
801
+ except Exception as e:
802
+ return {"error": str(e)}
803
+
804
+ async def ai_tutor_chat_async(session_id, student_query, request_type):
805
+ try:
806
+ async with sse_client(SERVER_URL) as (sse, write):
807
+ async with ClientSession(sse, write) as session:
808
+ await session.initialize()
809
+ response = await session.call_tool("ai_tutor_chat", {
810
+ "session_id": session_id,
811
+ "student_query": student_query,
812
+ "request_type": request_type
813
+ })
814
+ return await extract_response_content(response)
815
+ except Exception as e:
816
+ return {"error": str(e)}
817
+
818
+ async def get_step_by_step_guidance_async(session_id, concept, current_step):
819
+ try:
820
+ async with sse_client(SERVER_URL) as (sse, write):
821
+ async with ClientSession(sse, write) as session:
822
+ await session.initialize()
823
+ response = await session.call_tool("get_step_by_step_guidance", {
824
+ "session_id": session_id,
825
+ "concept": concept,
826
+ "current_step": current_step
827
+ })
828
+ return await extract_response_content(response)
829
+ except Exception as e:
830
+ return {"error": str(e)}
831
+
832
+ async def get_alternative_explanations_async(session_id, concept, explanation_types):
833
+ try:
834
+ async with sse_client(SERVER_URL) as (sse, write):
835
+ async with ClientSession(sse, write) as session:
836
+ await session.initialize()
837
+ response = await session.call_tool("get_alternative_explanations", {
838
+ "session_id": session_id,
839
+ "concept": concept,
840
+ "explanation_types": explanation_types
841
+ })
842
+ return await extract_response_content(response)
843
+ except Exception as e:
844
+ return {"error": str(e)}
845
+
846
+ async def end_tutoring_session_async(session_id, session_summary):
847
+ try:
848
+ async with sse_client(SERVER_URL) as (sse, write):
849
+ async with ClientSession(sse, write) as session:
850
+ await session.initialize()
851
+ response = await session.call_tool("end_tutoring_session", {
852
+ "session_id": session_id,
853
+ "session_summary": session_summary
854
+ })
855
+ return await extract_response_content(response)
856
+ except Exception as e:
857
+ return {"error": str(e)}
858
+
859
+ # Content Generation async functions
860
+ async def generate_interactive_exercise_async(concept, exercise_type, difficulty_level, student_level):
861
+ try:
862
+ async with sse_client(SERVER_URL) as (sse, write):
863
+ async with ClientSession(sse, write) as session:
864
+ await session.initialize()
865
+ response = await session.call_tool("generate_interactive_exercise", {
866
+ "concept": concept,
867
+ "exercise_type": exercise_type,
868
+ "difficulty_level": difficulty_level,
869
+ "student_level": student_level
870
+ })
871
+ return await extract_response_content(response)
872
+ except Exception as e:
873
+ return {"error": str(e)}
874
+
875
+ async def generate_scenario_based_learning_async(concept, scenario_type, complexity_level):
876
+ try:
877
+ async with sse_client(SERVER_URL) as (sse, write):
878
+ async with ClientSession(sse, write) as session:
879
+ await session.initialize()
880
+ response = await session.call_tool("generate_scenario_based_learning", {
881
+ "concept": concept,
882
+ "scenario_type": scenario_type,
883
+ "complexity_level": complexity_level
884
+ })
885
+ return await extract_response_content(response)
886
+ except Exception as e:
887
+ return {"error": str(e)}
888
+
889
+ async def generate_gamified_content_async(concept, game_type, target_age_group):
890
+ try:
891
+ async with sse_client(SERVER_URL) as (sse, write):
892
+ async with ClientSession(sse, write) as session:
893
+ await session.initialize()
894
+ response = await session.call_tool("generate_gamified_content", {
895
+ "concept": concept,
896
+ "game_type": game_type,
897
+ "target_age_group": target_age_group
898
+ })
899
+ return await extract_response_content(response)
900
+ except Exception as e:
901
+ return {"error": str(e)}
902
+
903
  # Create Gradio interface
904
  def create_gradio_interface():
905
  # Set a default student ID for the demo
 
1265
  inputs=[doc_input],
1266
  outputs=[doc_output]
1267
  )
1268
+
1269
+ # Tab 4: AI Tutoring
1270
+ with gr.Tab("4 🤖 AI Tutoring", elem_id="ai_tutoring_tab"):
1271
+ gr.Markdown("## Contextualized AI Tutoring")
1272
+ gr.Markdown("Experience personalized AI tutoring with step-by-step guidance and alternative explanations.")
1273
+
1274
+ with gr.Accordion("ℹ️ How AI Tutoring Works", open=False):
1275
+ gr.Markdown("""
1276
+ ### 🎯 Contextualized Learning
1277
+ - **Session Memory**: AI remembers your conversation and adapts responses
1278
+ - **Step-by-Step Guidance**: Break down complex concepts into manageable steps
1279
+ - **Alternative Explanations**: Multiple ways to understand the same concept
1280
+ - **Personalized Feedback**: Responses tailored to your understanding level
1281
+
1282
+ ### 🚀 Getting Started
1283
+ 1. Start a tutoring session with your preferred subject
1284
+ 2. Ask questions or request explanations
1285
+ 3. Get step-by-step guidance for complex topics
1286
+ 4. Request alternative explanations if needed
1287
+ 5. End session to get a comprehensive summary
1288
+ """)
1289
+
1290
+ # Tutoring Session Management
1291
+ with gr.Accordion("📚 Start Tutoring Session", open=True):
1292
+ with gr.Row():
1293
+ with gr.Column():
1294
+ tutor_student_id = gr.Textbox(label="Student ID", value=student_id)
1295
+ tutor_subject = gr.Textbox(label="Subject", value="Mathematics", placeholder="e.g., Mathematics, Physics, Chemistry")
1296
+ tutor_objectives = gr.Textbox(
1297
+ label="Learning Objectives (optional)",
1298
+ placeholder="e.g., Understand quadratic equations, Learn calculus basics",
1299
+ lines=2
1300
+ )
1301
+ start_tutor_btn = gr.Button("Start Tutoring Session", variant="primary")
1302
+
1303
+ with gr.Column():
1304
+ tutor_session_output = gr.JSON(label="Session Information")
1305
+
1306
+ # AI Chat Interface
1307
+ with gr.Accordion("💬 Chat with AI Tutor", open=True):
1308
+ with gr.Row():
1309
+ with gr.Column():
1310
+ chat_session_id = gr.Textbox(label="Session ID", placeholder="Enter session ID from above")
1311
+ chat_query = gr.Textbox(
1312
+ label="Ask Your Question",
1313
+ placeholder="e.g., How do I solve quadratic equations?",
1314
+ lines=3
1315
+ )
1316
+ chat_request_type = gr.Dropdown(
1317
+ choices=["explanation", "step_by_step", "alternative", "practice", "clarification"],
1318
+ value="explanation",
1319
+ label="Request Type"
1320
+ )
1321
+ chat_btn = gr.Button("Ask AI Tutor", variant="primary")
1322
+
1323
+ with gr.Column():
1324
+ chat_response = gr.JSON(label="AI Tutor Response")
1325
+
1326
+ # Step-by-Step Guidance
1327
+ with gr.Accordion("📋 Step-by-Step Guidance", open=True):
1328
+ with gr.Row():
1329
+ with gr.Column():
1330
+ step_session_id = gr.Textbox(label="Session ID")
1331
+ step_concept = gr.Textbox(label="Concept", placeholder="e.g., Solving quadratic equations")
1332
+ step_current = gr.Number(label="Current Step", value=1, minimum=1)
1333
+ get_steps_btn = gr.Button("Get Step-by-Step Guidance")
1334
+
1335
+ with gr.Column():
1336
+ steps_output = gr.JSON(label="Step-by-Step Guidance")
1337
+
1338
+ # Alternative Explanations
1339
+ with gr.Accordion("🔄 Alternative Explanations", open=True):
1340
+ with gr.Row():
1341
+ with gr.Column():
1342
+ alt_session_id = gr.Textbox(label="Session ID")
1343
+ alt_concept = gr.Textbox(label="Concept", placeholder="e.g., Photosynthesis")
1344
+ alt_types = gr.CheckboxGroup(
1345
+ choices=["visual", "analogy", "real_world", "simplified", "technical"],
1346
+ value=["visual", "analogy", "real_world"],
1347
+ label="Explanation Types"
1348
+ )
1349
+ get_alt_btn = gr.Button("Get Alternative Explanations")
1350
+
1351
+ with gr.Column():
1352
+ alt_output = gr.JSON(label="Alternative Explanations")
1353
+
1354
+ # Session Management
1355
+ with gr.Accordion("🔚 End Session & Summary", open=True):
1356
+ with gr.Row():
1357
+ with gr.Column():
1358
+ end_session_id = gr.Textbox(label="Session ID")
1359
+ session_summary = gr.Textbox(
1360
+ label="Session Summary (optional)",
1361
+ placeholder="What did you learn? Any feedback?",
1362
+ lines=3
1363
+ )
1364
+ end_session_btn = gr.Button("End Session & Get Summary", variant="secondary")
1365
+
1366
+ with gr.Column():
1367
+ session_end_output = gr.JSON(label="Session Summary")
1368
+
1369
+ # Connect all AI tutoring buttons
1370
+ start_tutor_btn.click(
1371
+ fn=lambda sid, subj, obj: sync_start_tutoring_session(sid, subj, obj.split(',') if obj else []),
1372
+ inputs=[tutor_student_id, tutor_subject, tutor_objectives],
1373
+ outputs=[tutor_session_output]
1374
+ )
1375
+
1376
+ chat_btn.click(
1377
+ fn=sync_ai_tutor_chat,
1378
+ inputs=[chat_session_id, chat_query, chat_request_type],
1379
+ outputs=[chat_response]
1380
+ )
1381
+
1382
+ get_steps_btn.click(
1383
+ fn=sync_get_step_by_step_guidance,
1384
+ inputs=[step_session_id, step_concept, step_current],
1385
+ outputs=[steps_output]
1386
+ )
1387
+
1388
+ get_alt_btn.click(
1389
+ fn=sync_get_alternative_explanations,
1390
+ inputs=[alt_session_id, alt_concept, alt_types],
1391
+ outputs=[alt_output]
1392
+ )
1393
+
1394
+ end_session_btn.click(
1395
+ fn=sync_end_tutoring_session,
1396
+ inputs=[end_session_id, session_summary],
1397
+ outputs=[session_end_output]
1398
+ )
1399
+
1400
+ # Tab 5: Content Generation
1401
+ with gr.Tab("5 🎨 Content Generation", elem_id="content_generation_tab"):
1402
+ gr.Markdown("## Advanced Content Generation")
1403
+ gr.Markdown("Generate interactive exercises, scenarios, and gamified content automatically.")
1404
+
1405
+ # Interactive Exercise Generation
1406
+ with gr.Accordion("🎯 Interactive Exercise Generation", open=True):
1407
+ with gr.Row():
1408
+ with gr.Column():
1409
+ ex_concept = gr.Textbox(label="Concept", placeholder="e.g., Photosynthesis, Linear Algebra")
1410
+ ex_type = gr.Dropdown(
1411
+ choices=["problem_solving", "simulation", "case_study", "lab", "project"],
1412
+ value="problem_solving",
1413
+ label="Exercise Type"
1414
+ )
1415
+ ex_difficulty = gr.Slider(minimum=0.1, maximum=1.0, value=0.5, step=0.1, label="Difficulty Level")
1416
+ ex_level = gr.Dropdown(
1417
+ choices=["beginner", "intermediate", "advanced"],
1418
+ value="intermediate",
1419
+ label="Student Level"
1420
+ )
1421
+ gen_exercise_btn = gr.Button("Generate Interactive Exercise", variant="primary")
1422
+
1423
+ with gr.Column():
1424
+ exercise_output = gr.JSON(label="Generated Exercise")
1425
+
1426
+ # Scenario-Based Learning
1427
+ with gr.Accordion("🎭 Scenario-Based Learning", open=True):
1428
+ with gr.Row():
1429
+ with gr.Column():
1430
+ scenario_concept = gr.Textbox(label="Concept", placeholder="e.g., Climate Change, Economics")
1431
+ scenario_type = gr.Dropdown(
1432
+ choices=["real_world", "historical", "futuristic", "problem_solving"],
1433
+ value="real_world",
1434
+ label="Scenario Type"
1435
+ )
1436
+ scenario_complexity = gr.Dropdown(
1437
+ choices=["simple", "moderate", "complex"],
1438
+ value="moderate",
1439
+ label="Complexity Level"
1440
+ )
1441
+ gen_scenario_btn = gr.Button("Generate Scenario", variant="primary")
1442
+
1443
+ with gr.Column():
1444
+ scenario_output = gr.JSON(label="Generated Scenario")
1445
+
1446
+ # Gamified Content
1447
+ with gr.Accordion("🎮 Gamified Content Generation", open=True):
1448
+ with gr.Row():
1449
+ with gr.Column():
1450
+ game_concept = gr.Textbox(label="Concept", placeholder="e.g., Fractions, Chemical Reactions")
1451
+ game_type = gr.Dropdown(
1452
+ choices=["quest", "puzzle", "simulation", "competition", "story"],
1453
+ value="quest",
1454
+ label="Game Type"
1455
+ )
1456
+ game_age = gr.Dropdown(
1457
+ choices=["child", "teen", "adult"],
1458
+ value="teen",
1459
+ label="Target Age Group"
1460
+ )
1461
+ gen_game_btn = gr.Button("Generate Gamified Content", variant="primary")
1462
+
1463
+ with gr.Column():
1464
+ game_output = gr.JSON(label="Generated Game Content")
1465
+
1466
+ # Connect content generation buttons
1467
+ gen_exercise_btn.click(
1468
+ fn=sync_generate_interactive_exercise,
1469
+ inputs=[ex_concept, ex_type, ex_difficulty, ex_level],
1470
+ outputs=[exercise_output]
1471
+ )
1472
+
1473
+ gen_scenario_btn.click(
1474
+ fn=sync_generate_scenario_based_learning,
1475
+ inputs=[scenario_concept, scenario_type, scenario_complexity],
1476
+ outputs=[scenario_output]
1477
+ )
1478
+
1479
+ gen_game_btn.click(
1480
+ fn=sync_generate_gamified_content,
1481
+ inputs=[game_concept, game_type, game_age],
1482
+ outputs=[game_output]
1483
+ )
1484
+
1485
+ # Tab 6: Adaptive Learning
1486
+ with gr.Tab("6 🧠 Adaptive Learning", elem_id="adaptive_learning_tab"):
1487
  gr.Markdown("## Adaptive Learning System")
1488
  gr.Markdown("Experience personalized learning with real-time adaptation based on your performance.")
1489
 
 
1652
  - **Engagement Metrics**: Measures learning engagement
1653
  """)
1654
 
1655
+ # Tab 7: Data Analytics
1656
+ with gr.Tab("7 Data Analytics", elem_id="data_analytics_tab"):
1657
  gr.Markdown("## Plagiarism Detection")
1658
 
1659
  with gr.Row():
docs/AI_INTEGRATION_FEATURES.md ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI Integration and Capabilities - TutorX-MCP
2
+
3
+ ## Overview
4
+
5
+ This document describes the enhanced AI integration and capabilities implemented in TutorX-MCP, focusing on contextualized AI tutoring and advanced automated content generation.
6
+
7
+ ## 🤖 Contextualized AI Tutoring
8
+
9
+ ### Features
10
+
11
+ #### 1. **Session-Based Tutoring**
12
+ - **Persistent Context**: AI maintains conversation history and adapts responses
13
+ - **Student Profiling**: Tracks understanding levels and learning preferences
14
+ - **Subject Specialization**: Tailored tutoring for specific subjects
15
+
16
+ #### 2. **Step-by-Step Guidance**
17
+ - **Progressive Learning**: Breaks complex concepts into manageable steps
18
+ - **Adaptive Pacing**: Adjusts based on student understanding
19
+ - **Checkpoint Validation**: Verifies understanding at key points
20
+
21
+ #### 3. **Alternative Explanations**
22
+ - **Multiple Approaches**: Visual, analogy-based, real-world applications
23
+ - **Learning Style Adaptation**: Matches student's preferred learning style
24
+ - **Difficulty Scaling**: Provides simplified or technical explanations as needed
25
+
26
+ ### API Endpoints
27
+
28
+ #### Start Tutoring Session
29
+ ```http
30
+ POST /api/start-tutoring-session
31
+ Content-Type: application/json
32
+
33
+ {
34
+ "student_id": "student_001",
35
+ "subject": "Mathematics",
36
+ "learning_objectives": ["Understand quadratic equations", "Learn factoring"]
37
+ }
38
+ ```
39
+
40
+ #### Chat with AI Tutor
41
+ ```http
42
+ POST /api/ai-tutor-chat
43
+ Content-Type: application/json
44
+
45
+ {
46
+ "session_id": "session_uuid",
47
+ "student_query": "How do I solve quadratic equations?",
48
+ "request_type": "step_by_step"
49
+ }
50
+ ```
51
+
52
+ #### Get Step-by-Step Guidance
53
+ ```http
54
+ POST /api/step-by-step-guidance
55
+ Content-Type: application/json
56
+
57
+ {
58
+ "session_id": "session_uuid",
59
+ "concept": "Solving quadratic equations",
60
+ "current_step": 1
61
+ }
62
+ ```
63
+
64
+ #### Get Alternative Explanations
65
+ ```http
66
+ POST /api/alternative-explanations
67
+ Content-Type: application/json
68
+
69
+ {
70
+ "session_id": "session_uuid",
71
+ "concept": "Quadratic formula",
72
+ "explanation_types": ["visual", "analogy", "real_world"]
73
+ }
74
+ ```
75
+
76
+ ## 🎨 Advanced Automated Content Generation
77
+
78
+ ### Features
79
+
80
+ #### 1. **Interactive Exercise Generation**
81
+ - **Multiple Exercise Types**: Problem-solving, simulations, case studies, labs, projects
82
+ - **Adaptive Difficulty**: Automatically calibrated based on student level
83
+ - **Assessment Integration**: Built-in evaluation criteria and rubrics
84
+
85
+ #### 2. **Scenario-Based Learning**
86
+ - **Realistic Contexts**: Real-world, historical, and futuristic scenarios
87
+ - **Decision Points**: Interactive choices with consequences
88
+ - **Multi-Path Solutions**: Multiple valid approaches to problems
89
+
90
+ #### 3. **Gamified Content**
91
+ - **Game Mechanics**: Quests, puzzles, simulations, competitions
92
+ - **Progressive Difficulty**: Leveled content with achievements
93
+ - **Social Features**: Collaborative and competitive elements
94
+
95
+ #### 4. **Multi-Modal Content**
96
+ - **Learning Style Support**: Visual, auditory, kinesthetic, reading/writing
97
+ - **Accessibility Features**: Content adapted for different abilities
98
+ - **Technology Integration**: Enhanced with digital tools
99
+
100
+ ### API Endpoints
101
+
102
+ #### Generate Interactive Exercise
103
+ ```http
104
+ POST /api/generate-interactive-exercise
105
+ Content-Type: application/json
106
+
107
+ {
108
+ "concept": "Photosynthesis",
109
+ "exercise_type": "simulation",
110
+ "difficulty_level": 0.6,
111
+ "student_level": "intermediate"
112
+ }
113
+ ```
114
+
115
+ #### Generate Scenario-Based Learning
116
+ ```http
117
+ POST /api/generate-scenario-based-learning
118
+ Content-Type: application/json
119
+
120
+ {
121
+ "concept": "Climate Change",
122
+ "scenario_type": "real_world",
123
+ "complexity_level": "moderate"
124
+ }
125
+ ```
126
+
127
+ #### Generate Gamified Content
128
+ ```http
129
+ POST /api/generate-gamified-content
130
+ Content-Type: application/json
131
+
132
+ {
133
+ "concept": "Fractions",
134
+ "game_type": "quest",
135
+ "target_age_group": "teen"
136
+ }
137
+ ```
138
+
139
+ ## 🚀 Usage Examples
140
+
141
+ ### Example 1: Complete Tutoring Session
142
+
143
+ ```python
144
+ # Start session
145
+ session = await start_tutoring_session(
146
+ student_id="student_001",
147
+ subject="Physics",
148
+ learning_objectives=["Understand Newton's laws"]
149
+ )
150
+
151
+ # Chat with tutor
152
+ response = await ai_tutor_chat(
153
+ session_id=session["session_id"],
154
+ student_query="What is Newton's first law?",
155
+ request_type="explanation"
156
+ )
157
+
158
+ # Get step-by-step guidance
159
+ steps = await get_step_by_step_guidance(
160
+ session_id=session["session_id"],
161
+ concept="Newton's first law",
162
+ current_step=1
163
+ )
164
+
165
+ # End session
166
+ summary = await end_tutoring_session(
167
+ session_id=session["session_id"],
168
+ session_summary="Learned about Newton's laws"
169
+ )
170
+ ```
171
+
172
+ ### Example 2: Content Generation Workflow
173
+
174
+ ```python
175
+ # Generate interactive exercise
176
+ exercise = await generate_interactive_exercise(
177
+ concept="Chemical Reactions",
178
+ exercise_type="lab",
179
+ difficulty_level=0.7,
180
+ student_level="advanced"
181
+ )
182
+
183
+ # Generate scenario
184
+ scenario = await generate_scenario_based_learning(
185
+ concept="Environmental Science",
186
+ scenario_type="real_world",
187
+ complexity_level="complex"
188
+ )
189
+
190
+ # Generate game
191
+ game = await generate_gamified_content(
192
+ concept="Algebra",
193
+ game_type="puzzle",
194
+ target_age_group="teen"
195
+ )
196
+ ```
197
+
198
+ ## 🔧 Technical Implementation
199
+
200
+ ### Architecture
201
+ - **Modular Design**: Separate modules for tutoring and content generation
202
+ - **Session Management**: In-memory session storage with context preservation
203
+ - **AI Integration**: Powered by Google Gemini Flash models
204
+ - **API Layer**: RESTful endpoints with comprehensive error handling
205
+
206
+ ### Key Components
207
+ - `ai_tutor_tools.py`: Contextualized tutoring functionality
208
+ - `content_generation_tools.py`: Advanced content generation
209
+ - `TutoringSession` class: Session state management
210
+ - Gradio interface: User-friendly web interface
211
+
212
+ ### Quality Assurance
213
+ - **Content Validation**: Automated quality checking
214
+ - **Error Handling**: Comprehensive error management
215
+ - **Testing**: Automated test suite for all features
216
+
217
+ ## 📊 Benefits
218
+
219
+ ### For Students
220
+ - **Personalized Learning**: Adapted to individual needs and pace
221
+ - **Multiple Learning Paths**: Various approaches to understand concepts
222
+ - **Engaging Content**: Interactive and gamified learning experiences
223
+ - **Immediate Feedback**: Real-time guidance and support
224
+
225
+ ### For Educators
226
+ - **Content Creation**: Automated generation of high-quality materials
227
+ - **Assessment Tools**: Built-in evaluation and rubrics
228
+ - **Analytics**: Detailed insights into student progress
229
+ - **Scalability**: Support for multiple students simultaneously
230
+
231
+ ## 🔮 Future Enhancements
232
+
233
+ - **Voice Integration**: Speech-to-text and text-to-speech capabilities
234
+ - **Visual Content**: Automatic diagram and chart generation
235
+ - **Collaborative Learning**: Multi-student tutoring sessions
236
+ - **Advanced Analytics**: Predictive learning analytics
237
+ - **Mobile Optimization**: Enhanced mobile experience
mcp_server/server.py CHANGED
@@ -57,6 +57,8 @@ from mcp_server.tools import interaction_tools
57
  from mcp_server.tools import ocr_tools
58
  from mcp_server.tools import learning_path_tools
59
  from mcp_server.tools import concept_graph_tools
 
 
60
 
61
 
62
  # Mount the SSE transport for MCP at '/sse/' (with trailing slash)
@@ -242,6 +244,154 @@ async def get_quiz_session_status_endpoint(request: dict):
242
  raise HTTPException(status_code=400, detail="session_id is required")
243
  return await get_quiz_session_status_tool(session_id)
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  # Entrypoint for running with MCP SSE transport
246
  if __name__ == "__main__":
247
  mcp.run(transport="sse")
 
57
  from mcp_server.tools import ocr_tools
58
  from mcp_server.tools import learning_path_tools
59
  from mcp_server.tools import concept_graph_tools
60
+ from mcp_server.tools import ai_tutor_tools
61
+ from mcp_server.tools import content_generation_tools
62
 
63
 
64
  # Mount the SSE transport for MCP at '/sse/' (with trailing slash)
 
244
  raise HTTPException(status_code=400, detail="session_id is required")
245
  return await get_quiz_session_status_tool(session_id)
246
 
247
+ # API endpoints - AI Tutoring
248
+ from mcp_server.tools.ai_tutor_tools import (
249
+ start_tutoring_session,
250
+ ai_tutor_chat,
251
+ get_step_by_step_guidance,
252
+ get_alternative_explanations,
253
+ update_student_understanding,
254
+ get_tutoring_session_status,
255
+ end_tutoring_session,
256
+ list_active_tutoring_sessions
257
+ )
258
+
259
+ @api_app.post("/api/start-tutoring-session")
260
+ async def start_tutoring_session_endpoint(request: dict):
261
+ student_id = request.get("student_id")
262
+ subject = request.get("subject", "general")
263
+ learning_objectives = request.get("learning_objectives", [])
264
+ if not student_id:
265
+ raise HTTPException(status_code=400, detail="student_id is required")
266
+ return await start_tutoring_session(student_id, subject, learning_objectives)
267
+
268
+ @api_app.post("/api/ai-tutor-chat")
269
+ async def ai_tutor_chat_endpoint(request: dict):
270
+ session_id = request.get("session_id")
271
+ student_query = request.get("student_query")
272
+ request_type = request.get("request_type", "explanation")
273
+ if not session_id or not student_query:
274
+ raise HTTPException(status_code=400, detail="session_id and student_query are required")
275
+ return await ai_tutor_chat(session_id, student_query, request_type)
276
+
277
+ @api_app.post("/api/step-by-step-guidance")
278
+ async def step_by_step_guidance_endpoint(request: dict):
279
+ session_id = request.get("session_id")
280
+ concept = request.get("concept")
281
+ current_step = request.get("current_step", 1)
282
+ if not session_id or not concept:
283
+ raise HTTPException(status_code=400, detail="session_id and concept are required")
284
+ return await get_step_by_step_guidance(session_id, concept, current_step)
285
+
286
+ @api_app.post("/api/alternative-explanations")
287
+ async def alternative_explanations_endpoint(request: dict):
288
+ session_id = request.get("session_id")
289
+ concept = request.get("concept")
290
+ explanation_types = request.get("explanation_types", [])
291
+ if not session_id or not concept:
292
+ raise HTTPException(status_code=400, detail="session_id and concept are required")
293
+ return await get_alternative_explanations(session_id, concept, explanation_types)
294
+
295
+ @api_app.post("/api/update-student-understanding")
296
+ async def update_student_understanding_endpoint(request: dict):
297
+ session_id = request.get("session_id")
298
+ concept = request.get("concept")
299
+ understanding_level = request.get("understanding_level")
300
+ feedback = request.get("feedback", "")
301
+ if not session_id or not concept or understanding_level is None:
302
+ raise HTTPException(status_code=400, detail="session_id, concept, and understanding_level are required")
303
+ return await update_student_understanding(session_id, concept, understanding_level, feedback)
304
+
305
+ @api_app.get("/api/tutoring-session-status/{session_id}")
306
+ async def tutoring_session_status_endpoint(session_id: str):
307
+ return await get_tutoring_session_status(session_id)
308
+
309
+ @api_app.post("/api/end-tutoring-session")
310
+ async def end_tutoring_session_endpoint(request: dict):
311
+ session_id = request.get("session_id")
312
+ session_summary = request.get("session_summary", "")
313
+ if not session_id:
314
+ raise HTTPException(status_code=400, detail="session_id is required")
315
+ return await end_tutoring_session(session_id, session_summary)
316
+
317
+ @api_app.get("/api/active-tutoring-sessions")
318
+ async def active_tutoring_sessions_endpoint(student_id: str = None):
319
+ return await list_active_tutoring_sessions(student_id)
320
+
321
+ # API endpoints - Content Generation
322
+ from mcp_server.tools.content_generation_tools import (
323
+ generate_interactive_exercise,
324
+ generate_adaptive_content_sequence,
325
+ generate_scenario_based_learning,
326
+ generate_multimodal_content,
327
+ generate_adaptive_assessment,
328
+ generate_gamified_content,
329
+ validate_generated_content
330
+ )
331
+
332
+ @api_app.post("/api/generate-interactive-exercise")
333
+ async def generate_interactive_exercise_endpoint(request: dict):
334
+ concept = request.get("concept")
335
+ exercise_type = request.get("exercise_type", "problem_solving")
336
+ difficulty_level = request.get("difficulty_level", 0.5)
337
+ student_level = request.get("student_level", "intermediate")
338
+ if not concept:
339
+ raise HTTPException(status_code=400, detail="concept is required")
340
+ return await generate_interactive_exercise(concept, exercise_type, difficulty_level, student_level)
341
+
342
+ @api_app.post("/api/generate-adaptive-content-sequence")
343
+ async def generate_adaptive_content_sequence_endpoint(request: dict):
344
+ topic = request.get("topic")
345
+ student_profile = request.get("student_profile", {})
346
+ sequence_length = request.get("sequence_length", 5)
347
+ if not topic:
348
+ raise HTTPException(status_code=400, detail="topic is required")
349
+ return await generate_adaptive_content_sequence(topic, student_profile, sequence_length)
350
+
351
+ @api_app.post("/api/generate-scenario-based-learning")
352
+ async def generate_scenario_based_learning_endpoint(request: dict):
353
+ concept = request.get("concept")
354
+ scenario_type = request.get("scenario_type", "real_world")
355
+ complexity_level = request.get("complexity_level", "moderate")
356
+ if not concept:
357
+ raise HTTPException(status_code=400, detail="concept is required")
358
+ return await generate_scenario_based_learning(concept, scenario_type, complexity_level)
359
+
360
+ @api_app.post("/api/generate-multimodal-content")
361
+ async def generate_multimodal_content_endpoint(request: dict):
362
+ concept = request.get("concept")
363
+ modalities = request.get("modalities", ["visual", "auditory", "kinesthetic", "reading"])
364
+ target_audience = request.get("target_audience", "general")
365
+ if not concept:
366
+ raise HTTPException(status_code=400, detail="concept is required")
367
+ return await generate_multimodal_content(concept, modalities, target_audience)
368
+
369
+ @api_app.post("/api/generate-adaptive-assessment")
370
+ async def generate_adaptive_assessment_endpoint(request: dict):
371
+ concept = request.get("concept")
372
+ assessment_type = request.get("assessment_type", "formative")
373
+ student_data = request.get("student_data", {})
374
+ if not concept:
375
+ raise HTTPException(status_code=400, detail="concept is required")
376
+ return await generate_adaptive_assessment(concept, assessment_type, student_data)
377
+
378
+ @api_app.post("/api/generate-gamified-content")
379
+ async def generate_gamified_content_endpoint(request: dict):
380
+ concept = request.get("concept")
381
+ game_type = request.get("game_type", "quest")
382
+ target_age_group = request.get("target_age_group", "teen")
383
+ if not concept:
384
+ raise HTTPException(status_code=400, detail="concept is required")
385
+ return await generate_gamified_content(concept, game_type, target_age_group)
386
+
387
+ @api_app.post("/api/validate-content")
388
+ async def validate_content_endpoint(request: dict):
389
+ content_data = request.get("content_data")
390
+ validation_criteria = request.get("validation_criteria", {})
391
+ if not content_data:
392
+ raise HTTPException(status_code=400, detail="content_data is required")
393
+ return await validate_generated_content(content_data, validation_criteria)
394
+
395
  # Entrypoint for running with MCP SSE transport
396
  if __name__ == "__main__":
397
  mcp.run(transport="sse")
mcp_server/tools/ai_tutor_tools.py ADDED
@@ -0,0 +1,650 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Contextualized AI Tutoring tools for TutorX.
3
+ Provides step-by-step guidance, alternative explanations, and conversational AI tutoring.
4
+ """
5
+
6
+ import json
7
+ import uuid
8
+ from datetime import datetime, timedelta
9
+ from typing import Dict, Any, List, Optional
10
+ from mcp_server.mcp_instance import mcp
11
+ from mcp_server.model.gemini_flash import GeminiFlash
12
+
13
+ MODEL = GeminiFlash()
14
+
15
+ # Tutoring session storage
16
+ tutoring_sessions = {}
17
+
18
+ def extract_json_from_text(text: str):
19
+ """Extract JSON from text response"""
20
+ import re
21
+ if not text or not isinstance(text, str):
22
+ return None
23
+ # Remove code fences
24
+ text = re.sub(r'^\s*```(?:json)?\s*', '', text, flags=re.IGNORECASE)
25
+ text = re.sub(r'\s*```\s*$', '', text, flags=re.IGNORECASE)
26
+ text = text.strip()
27
+ # Remove trailing commas
28
+ text = re.sub(r',([ \t\r\n]*[}}\]])', r'\1', text)
29
+ return json.loads(text)
30
+
31
+ class TutoringSession:
32
+ """Manages a tutoring session with context and memory"""
33
+
34
+ def __init__(self, session_id: str, student_id: str, subject: str = "general"):
35
+ self.session_id = session_id
36
+ self.student_id = student_id
37
+ self.subject = subject
38
+ self.created_at = datetime.utcnow()
39
+ self.last_activity = datetime.utcnow()
40
+ self.conversation_history = []
41
+ self.current_topic = None
42
+ self.learning_objectives = []
43
+ self.student_understanding_level = 0.5 # 0.0 to 1.0
44
+ self.preferred_explanation_style = "detailed" # detailed, simple, visual, step-by-step
45
+ self.difficulty_preference = 0.5 # 0.0 to 1.0
46
+
47
+ def add_interaction(self, query: str, response: str, interaction_type: str = "question"):
48
+ """Add an interaction to the session history"""
49
+ self.conversation_history.append({
50
+ "timestamp": datetime.utcnow().isoformat(),
51
+ "query": query,
52
+ "response": response,
53
+ "type": interaction_type,
54
+ "understanding_level": self.student_understanding_level
55
+ })
56
+ self.last_activity = datetime.utcnow()
57
+
58
+ def get_context_summary(self) -> str:
59
+ """Generate a context summary for the AI tutor"""
60
+ recent_interactions = self.conversation_history[-5:] # Last 5 interactions
61
+
62
+ context = f"""
63
+ Session Context:
64
+ - Student ID: {self.student_id}
65
+ - Subject: {self.subject}
66
+ - Current Topic: {self.current_topic or 'Not specified'}
67
+ - Understanding Level: {self.student_understanding_level:.2f}/1.0
68
+ - Preferred Style: {self.preferred_explanation_style}
69
+ - Session Duration: {(datetime.utcnow() - self.created_at).total_seconds() / 60:.1f} minutes
70
+
71
+ Recent Conversation:
72
+ """
73
+
74
+ for interaction in recent_interactions:
75
+ context += f"\nStudent: {interaction['query']}\nTutor: {interaction['response'][:100]}...\n"
76
+
77
+ return context
78
+
79
+ @mcp.tool()
80
+ async def start_tutoring_session(student_id: str, subject: str = "general",
81
+ learning_objectives: List[str] = None) -> dict:
82
+ """
83
+ Start a new AI tutoring session with context management.
84
+
85
+ Args:
86
+ student_id: Student identifier
87
+ subject: Subject area for tutoring
88
+ learning_objectives: List of learning objectives for the session
89
+
90
+ Returns:
91
+ Dictionary with session information
92
+ """
93
+ try:
94
+ session_id = str(uuid.uuid4())
95
+ session = TutoringSession(session_id, student_id, subject)
96
+
97
+ if learning_objectives:
98
+ session.learning_objectives = learning_objectives
99
+
100
+ tutoring_sessions[session_id] = session
101
+
102
+ # Generate welcome message
103
+ prompt = f"""
104
+ You are an expert AI tutor starting a new tutoring session.
105
+
106
+ Student ID: {student_id}
107
+ Subject: {subject}
108
+ Learning Objectives: {learning_objectives or 'To be determined based on student needs'}
109
+
110
+ Generate a welcoming introduction that:
111
+ 1. Welcomes the student warmly
112
+ 2. Explains your role as their AI tutor
113
+ 3. Asks about their current understanding or what they'd like to learn
114
+ 4. Sets expectations for the tutoring session
115
+
116
+ Return a JSON object with:
117
+ - "welcome_message": friendly welcome text
118
+ - "suggested_topics": list of 3-5 topics they might want to explore
119
+ - "session_guidelines": brief explanation of how the tutoring works
120
+ """
121
+
122
+ response = await MODEL.generate_text(prompt, temperature=0.7)
123
+ welcome_data = extract_json_from_text(response)
124
+
125
+ return {
126
+ "success": True,
127
+ "session_id": session_id,
128
+ "student_id": student_id,
129
+ "subject": subject,
130
+ "created_at": session.created_at.isoformat(),
131
+ **welcome_data
132
+ }
133
+
134
+ except Exception as e:
135
+ return {
136
+ "success": False,
137
+ "error": f"Failed to start tutoring session: {str(e)}"
138
+ }
139
+
140
+ @mcp.tool()
141
+ async def ai_tutor_chat(session_id: str, student_query: str,
142
+ request_type: str = "explanation") -> dict:
143
+ """
144
+ Process student query with contextualized AI tutoring.
145
+
146
+ Args:
147
+ session_id: Active tutoring session ID
148
+ student_query: Student's question or request
149
+ request_type: Type of request ('explanation', 'step_by_step', 'alternative', 'practice', 'clarification')
150
+
151
+ Returns:
152
+ Dictionary with tutor response and guidance
153
+ """
154
+ try:
155
+ if session_id not in tutoring_sessions:
156
+ return {
157
+ "success": False,
158
+ "error": "Invalid session ID. Please start a new tutoring session."
159
+ }
160
+
161
+ session = tutoring_sessions[session_id]
162
+ context = session.get_context_summary()
163
+
164
+ # Analyze student query to understand their needs
165
+ analysis_prompt = f"""
166
+ Analyze this student query in the context of their tutoring session:
167
+
168
+ {context}
169
+
170
+ Student Query: "{student_query}"
171
+ Request Type: {request_type}
172
+
173
+ Analyze and return JSON with:
174
+ - "topic_identified": main topic/concept the student is asking about
175
+ - "difficulty_level": estimated difficulty (0.0 to 1.0)
176
+ - "understanding_gaps": potential areas where student might be confused
177
+ - "prerequisite_concepts": concepts student should know first
178
+ - "confidence_level": how confident the student seems (0.0 to 1.0)
179
+ """
180
+
181
+ analysis_response = await MODEL.generate_text(analysis_prompt, temperature=0.3)
182
+ analysis = extract_json_from_text(analysis_response)
183
+
184
+ # Update session context based on analysis
185
+ if analysis and "topic_identified" in analysis:
186
+ session.current_topic = analysis["topic_identified"]
187
+ if "difficulty_level" in analysis:
188
+ session.difficulty_preference = analysis["difficulty_level"]
189
+
190
+ # Generate appropriate response based on request type
191
+ if request_type == "step_by_step":
192
+ response_prompt = f"""
193
+ {context}
194
+
195
+ The student asked: "{student_query}"
196
+
197
+ Provide a detailed step-by-step explanation that:
198
+ 1. Breaks down the concept into manageable steps
199
+ 2. Uses simple, clear language appropriate for their level
200
+ 3. Includes examples for each step
201
+ 4. Checks understanding at key points
202
+ 5. Provides encouragement and support
203
+
204
+ Return JSON with:
205
+ - "step_by_step_explanation": detailed step-by-step guide
206
+ - "key_steps": list of main steps with brief descriptions
207
+ - "examples": relevant examples for each step
208
+ - "check_points": questions to verify understanding
209
+ - "encouragement": supportive message
210
+ """
211
+ elif request_type == "alternative":
212
+ response_prompt = f"""
213
+ {context}
214
+
215
+ The student asked: "{student_query}"
216
+
217
+ Provide alternative explanations using different approaches:
218
+ 1. Visual/spatial explanation
219
+ 2. Analogy-based explanation
220
+ 3. Real-world application
221
+ 4. Simplified version
222
+
223
+ Return JSON with:
224
+ - "visual_explanation": explanation using visual/spatial concepts
225
+ - "analogy_explanation": explanation using familiar analogies
226
+ - "real_world_application": how this applies in real life
227
+ - "simplified_version": very simple explanation
228
+ - "which_works_best": question asking which explanation resonates
229
+ """
230
+ else: # Default explanation
231
+ response_prompt = f"""
232
+ {context}
233
+
234
+ The student asked: "{student_query}"
235
+
236
+ Provide a comprehensive, personalized explanation that:
237
+ 1. Addresses their specific question directly
238
+ 2. Builds on their current understanding level
239
+ 3. Uses their preferred explanation style
240
+ 4. Includes relevant examples
241
+ 5. Suggests next steps for learning
242
+
243
+ Return JSON with:
244
+ - "main_explanation": comprehensive answer to their question
245
+ - "key_concepts": important concepts to remember
246
+ - "examples": relevant examples
247
+ - "next_steps": suggested follow-up activities
248
+ - "related_topics": topics they might want to explore next
249
+ """
250
+
251
+ tutor_response = await MODEL.generate_text(response_prompt, temperature=0.7)
252
+ response_data = extract_json_from_text(tutor_response)
253
+
254
+ # Add interaction to session history
255
+ session.add_interaction(
256
+ student_query,
257
+ response_data.get("main_explanation", str(response_data)),
258
+ request_type
259
+ )
260
+
261
+ return {
262
+ "success": True,
263
+ "session_id": session_id,
264
+ "request_type": request_type,
265
+ "analysis": analysis,
266
+ "response": response_data,
267
+ "session_stats": {
268
+ "interactions_count": len(session.conversation_history),
269
+ "current_topic": session.current_topic,
270
+ "understanding_level": session.student_understanding_level
271
+ }
272
+ }
273
+
274
+ except Exception as e:
275
+ return {
276
+ "success": False,
277
+ "error": f"Failed to process tutoring request: {str(e)}"
278
+ }
279
+
280
+ @mcp.tool()
281
+ async def get_step_by_step_guidance(session_id: str, concept: str,
282
+ current_step: int = 1) -> dict:
283
+ """
284
+ Provide detailed step-by-step guidance for learning a specific concept.
285
+
286
+ Args:
287
+ session_id: Active tutoring session ID
288
+ concept: The concept to provide guidance for
289
+ current_step: Current step the student is on (1-based)
290
+
291
+ Returns:
292
+ Dictionary with step-by-step guidance
293
+ """
294
+ try:
295
+ if session_id not in tutoring_sessions:
296
+ return {
297
+ "success": False,
298
+ "error": "Invalid session ID. Please start a new tutoring session."
299
+ }
300
+
301
+ session = tutoring_sessions[session_id]
302
+ context = session.get_context_summary()
303
+
304
+ prompt = f"""
305
+ {context}
306
+
307
+ Provide comprehensive step-by-step guidance for learning: "{concept}"
308
+ Current step: {current_step}
309
+
310
+ Create a structured learning path that:
311
+ 1. Breaks the concept into logical, sequential steps
312
+ 2. Provides clear explanations for each step
313
+ 3. Includes practice exercises for each step
314
+ 4. Offers multiple ways to understand each step
315
+ 5. Includes checkpoints to verify understanding
316
+
317
+ Return JSON with:
318
+ - "total_steps": total number of steps needed
319
+ - "current_step_details": detailed information about the current step
320
+ - "step_explanation": clear explanation of the current step
321
+ - "practice_exercises": 2-3 practice problems for this step
322
+ - "key_points": important points to remember
323
+ - "common_mistakes": common mistakes students make at this step
324
+ - "next_step_preview": brief preview of what comes next
325
+ - "prerequisite_check": what student should know before this step
326
+ - "mastery_indicators": how to know if student has mastered this step
327
+ """
328
+
329
+ response = await MODEL.generate_text(prompt, temperature=0.6)
330
+ guidance_data = extract_json_from_text(response)
331
+
332
+ return {
333
+ "success": True,
334
+ "session_id": session_id,
335
+ "concept": concept,
336
+ "current_step": current_step,
337
+ "guidance": guidance_data
338
+ }
339
+
340
+ except Exception as e:
341
+ return {
342
+ "success": False,
343
+ "error": f"Failed to generate step-by-step guidance: {str(e)}"
344
+ }
345
+
346
+ @mcp.tool()
347
+ async def get_alternative_explanations(session_id: str, concept: str,
348
+ explanation_types: List[str] = None) -> dict:
349
+ """
350
+ Generate alternative explanations for a concept using different approaches.
351
+
352
+ Args:
353
+ session_id: Active tutoring session ID
354
+ concept: The concept to explain
355
+ explanation_types: Types of explanations to generate
356
+
357
+ Returns:
358
+ Dictionary with alternative explanations
359
+ """
360
+ try:
361
+ if session_id not in tutoring_sessions:
362
+ return {
363
+ "success": False,
364
+ "error": "Invalid session ID. Please start a new tutoring session."
365
+ }
366
+
367
+ session = tutoring_sessions[session_id]
368
+ context = session.get_context_summary()
369
+
370
+ if not explanation_types:
371
+ explanation_types = ["visual", "analogy", "real_world", "simplified", "technical"]
372
+
373
+ prompt = f"""
374
+ {context}
375
+
376
+ Generate multiple alternative explanations for: "{concept}"
377
+
378
+ Create explanations using these approaches: {explanation_types}
379
+
380
+ For each explanation type, provide:
381
+ 1. A complete explanation using that approach
382
+ 2. Key benefits of this explanation style
383
+ 3. When this explanation works best
384
+ 4. Supporting examples or analogies
385
+
386
+ Return JSON with:
387
+ - "visual_explanation": explanation using visual/spatial concepts and imagery
388
+ - "analogy_explanation": explanation using familiar analogies and metaphors
389
+ - "real_world_explanation": explanation showing real-world applications
390
+ - "simplified_explanation": very simple, basic explanation
391
+ - "technical_explanation": detailed, technical explanation
392
+ - "story_explanation": explanation told as a story or narrative
393
+ - "comparison_explanation": explanation comparing to similar concepts
394
+ - "recommendation": which explanation might work best for this student
395
+ """
396
+
397
+ response = await MODEL.generate_text(prompt, temperature=0.7)
398
+ explanations_data = extract_json_from_text(response)
399
+
400
+ return {
401
+ "success": True,
402
+ "session_id": session_id,
403
+ "concept": concept,
404
+ "explanation_types": explanation_types,
405
+ "explanations": explanations_data
406
+ }
407
+
408
+ except Exception as e:
409
+ return {
410
+ "success": False,
411
+ "error": f"Failed to generate alternative explanations: {str(e)}"
412
+ }
413
+
414
+ @mcp.tool()
415
+ async def update_student_understanding(session_id: str, concept: str,
416
+ understanding_level: float,
417
+ feedback: str = "") -> dict:
418
+ """
419
+ Update student's understanding level and adapt tutoring accordingly.
420
+
421
+ Args:
422
+ session_id: Active tutoring session ID
423
+ concept: The concept being learned
424
+ understanding_level: Student's understanding level (0.0 to 1.0)
425
+ feedback: Optional feedback from student
426
+
427
+ Returns:
428
+ Dictionary with updated session information and recommendations
429
+ """
430
+ try:
431
+ if session_id not in tutoring_sessions:
432
+ return {
433
+ "success": False,
434
+ "error": "Invalid session ID. Please start a new tutoring session."
435
+ }
436
+
437
+ session = tutoring_sessions[session_id]
438
+
439
+ # Update session understanding level
440
+ session.student_understanding_level = understanding_level
441
+ session.current_topic = concept
442
+
443
+ # Generate adaptive recommendations based on understanding level
444
+ prompt = f"""
445
+ Student understanding update:
446
+ - Concept: {concept}
447
+ - Understanding Level: {understanding_level:.2f}/1.0
448
+ - Student Feedback: {feedback or 'No feedback provided'}
449
+ - Session Context: {session.get_context_summary()}
450
+
451
+ Based on this understanding level, provide adaptive recommendations:
452
+
453
+ Return JSON with:
454
+ - "understanding_assessment": assessment of student's current understanding
455
+ - "next_actions": recommended next steps based on understanding level
456
+ - "difficulty_adjustment": how to adjust difficulty (easier/harder/same)
457
+ - "focus_areas": specific areas that need more attention
458
+ - "encouragement": encouraging message appropriate for their level
459
+ - "study_strategies": personalized study strategies
460
+ - "time_estimate": estimated time to reach mastery
461
+ """
462
+
463
+ response = await MODEL.generate_text(prompt, temperature=0.6)
464
+ recommendations_data = extract_json_from_text(response)
465
+
466
+ # Add this update to conversation history
467
+ session.add_interaction(
468
+ f"Understanding update for {concept}: {understanding_level:.2f}",
469
+ f"Updated understanding and provided recommendations",
470
+ "understanding_update"
471
+ )
472
+
473
+ return {
474
+ "success": True,
475
+ "session_id": session_id,
476
+ "concept": concept,
477
+ "updated_understanding_level": understanding_level,
478
+ "recommendations": recommendations_data,
479
+ "session_stats": {
480
+ "interactions_count": len(session.conversation_history),
481
+ "current_topic": session.current_topic,
482
+ "understanding_level": session.student_understanding_level
483
+ }
484
+ }
485
+
486
+ except Exception as e:
487
+ return {
488
+ "success": False,
489
+ "error": f"Failed to update understanding: {str(e)}"
490
+ }
491
+
492
+ @mcp.tool()
493
+ async def get_tutoring_session_status(session_id: str) -> dict:
494
+ """
495
+ Get the current status and context of a tutoring session.
496
+
497
+ Args:
498
+ session_id: Tutoring session ID
499
+
500
+ Returns:
501
+ Dictionary with session status and statistics
502
+ """
503
+ try:
504
+ if session_id not in tutoring_sessions:
505
+ return {
506
+ "success": False,
507
+ "error": "Session not found"
508
+ }
509
+
510
+ session = tutoring_sessions[session_id]
511
+
512
+ return {
513
+ "success": True,
514
+ "session_id": session_id,
515
+ "student_id": session.student_id,
516
+ "subject": session.subject,
517
+ "current_topic": session.current_topic,
518
+ "created_at": session.created_at.isoformat(),
519
+ "last_activity": session.last_activity.isoformat(),
520
+ "duration_minutes": (datetime.utcnow() - session.created_at).total_seconds() / 60,
521
+ "understanding_level": session.student_understanding_level,
522
+ "preferred_style": session.preferred_explanation_style,
523
+ "learning_objectives": session.learning_objectives,
524
+ "interaction_count": len(session.conversation_history),
525
+ "recent_topics": list(set([
526
+ interaction.get("query", "")[:50]
527
+ for interaction in session.conversation_history[-5:]
528
+ ]))
529
+ }
530
+
531
+ except Exception as e:
532
+ return {
533
+ "success": False,
534
+ "error": f"Failed to get session status: {str(e)}"
535
+ }
536
+
537
+ @mcp.tool()
538
+ async def end_tutoring_session(session_id: str, session_summary: str = "") -> dict:
539
+ """
540
+ End a tutoring session and generate a summary.
541
+
542
+ Args:
543
+ session_id: Tutoring session ID
544
+ session_summary: Optional summary from student
545
+
546
+ Returns:
547
+ Dictionary with session summary and recommendations
548
+ """
549
+ try:
550
+ if session_id not in tutoring_sessions:
551
+ return {
552
+ "success": False,
553
+ "error": "Session not found"
554
+ }
555
+
556
+ session = tutoring_sessions[session_id]
557
+
558
+ # Generate session summary
559
+ prompt = f"""
560
+ Generate a comprehensive summary for this tutoring session:
561
+
562
+ {session.get_context_summary()}
563
+
564
+ Session Details:
565
+ - Duration: {(datetime.utcnow() - session.created_at).total_seconds() / 60:.1f} minutes
566
+ - Interactions: {len(session.conversation_history)}
567
+ - Final Understanding Level: {session.student_understanding_level:.2f}/1.0
568
+ - Student Summary: {session_summary or 'No summary provided'}
569
+
570
+ Return JSON with:
571
+ - "session_summary": comprehensive summary of what was covered
572
+ - "learning_achievements": what the student accomplished
573
+ - "areas_covered": topics and concepts discussed
574
+ - "understanding_progress": how understanding evolved during session
575
+ - "recommendations": recommendations for future study
576
+ - "next_session_suggestions": suggestions for next tutoring session
577
+ - "study_plan": personalized study plan based on session
578
+ - "strengths_identified": student strengths observed
579
+ - "areas_for_improvement": areas that need more work
580
+ """
581
+
582
+ response = await MODEL.generate_text(prompt, temperature=0.6)
583
+ summary_data = extract_json_from_text(response)
584
+
585
+ # Store session summary before removing
586
+ session_data = {
587
+ "session_id": session_id,
588
+ "student_id": session.student_id,
589
+ "subject": session.subject,
590
+ "duration_minutes": (datetime.utcnow() - session.created_at).total_seconds() / 60,
591
+ "interaction_count": len(session.conversation_history),
592
+ "final_understanding": session.student_understanding_level,
593
+ "summary": summary_data
594
+ }
595
+
596
+ # Remove session from active sessions
597
+ del tutoring_sessions[session_id]
598
+
599
+ return {
600
+ "success": True,
601
+ "session_ended": True,
602
+ **session_data
603
+ }
604
+
605
+ except Exception as e:
606
+ return {
607
+ "success": False,
608
+ "error": f"Failed to end session: {str(e)}"
609
+ }
610
+
611
+ @mcp.tool()
612
+ async def list_active_tutoring_sessions(student_id: str = None) -> dict:
613
+ """
614
+ List all active tutoring sessions, optionally filtered by student.
615
+
616
+ Args:
617
+ student_id: Optional student ID to filter sessions
618
+
619
+ Returns:
620
+ Dictionary with list of active sessions
621
+ """
622
+ try:
623
+ active_sessions = []
624
+
625
+ for session_id, session in tutoring_sessions.items():
626
+ if student_id is None or session.student_id == student_id:
627
+ active_sessions.append({
628
+ "session_id": session_id,
629
+ "student_id": session.student_id,
630
+ "subject": session.subject,
631
+ "current_topic": session.current_topic,
632
+ "created_at": session.created_at.isoformat(),
633
+ "last_activity": session.last_activity.isoformat(),
634
+ "duration_minutes": (datetime.utcnow() - session.created_at).total_seconds() / 60,
635
+ "understanding_level": session.student_understanding_level,
636
+ "interaction_count": len(session.conversation_history)
637
+ })
638
+
639
+ return {
640
+ "success": True,
641
+ "active_sessions": active_sessions,
642
+ "total_sessions": len(active_sessions),
643
+ "filtered_by_student": student_id is not None
644
+ }
645
+
646
+ except Exception as e:
647
+ return {
648
+ "success": False,
649
+ "error": f"Failed to list sessions: {str(e)}"
650
+ }
mcp_server/tools/content_generation_tools.py ADDED
@@ -0,0 +1,499 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Advanced Automated Content Generation tools for TutorX.
3
+ Generates interactive content, exercises, and adaptive learning materials.
4
+ """
5
+
6
+ import json
7
+ import uuid
8
+ from datetime import datetime
9
+ from typing import Dict, Any, List, Optional
10
+ from mcp_server.mcp_instance import mcp
11
+ from mcp_server.model.gemini_flash import GeminiFlash
12
+
13
+ MODEL = GeminiFlash()
14
+
15
+ def extract_json_from_text(text: str):
16
+ """Extract JSON from text response"""
17
+ import re
18
+ if not text or not isinstance(text, str):
19
+ return None
20
+ # Remove code fences
21
+ text = re.sub(r'^\s*```(?:json)?\s*', '', text, flags=re.IGNORECASE)
22
+ text = re.sub(r'\s*```\s*$', '', text, flags=re.IGNORECASE)
23
+ text = text.strip()
24
+ # Remove trailing commas
25
+ text = re.sub(r',([ \t\r\n]*[}}\]])', r'\1', text)
26
+ return json.loads(text)
27
+
28
+ @mcp.tool()
29
+ async def generate_interactive_exercise(concept: str, exercise_type: str = "problem_solving",
30
+ difficulty_level: float = 0.5,
31
+ student_level: str = "intermediate") -> dict:
32
+ """
33
+ Generate interactive exercises with multiple components and adaptive features.
34
+
35
+ Args:
36
+ concept: The concept to create exercises for
37
+ exercise_type: Type of exercise ('problem_solving', 'simulation', 'case_study', 'lab', 'project')
38
+ difficulty_level: Difficulty level (0.0 to 1.0)
39
+ student_level: Student's academic level
40
+
41
+ Returns:
42
+ Dictionary with interactive exercise content
43
+ """
44
+ try:
45
+ prompt = f"""
46
+ Create an interactive {exercise_type} exercise for the concept: "{concept}"
47
+
48
+ Exercise Parameters:
49
+ - Difficulty Level: {difficulty_level:.2f}/1.0
50
+ - Student Level: {student_level}
51
+ - Exercise Type: {exercise_type}
52
+
53
+ Generate a comprehensive interactive exercise that includes:
54
+ 1. Clear learning objectives
55
+ 2. Step-by-step instructions
56
+ 3. Interactive components that engage the student
57
+ 4. Multiple difficulty levels within the exercise
58
+ 5. Real-time feedback mechanisms
59
+ 6. Assessment criteria
60
+ 7. Extension activities for advanced students
61
+
62
+ Return JSON with:
63
+ - "exercise_id": unique identifier
64
+ - "title": engaging title for the exercise
65
+ - "learning_objectives": list of specific learning goals
66
+ - "introduction": engaging introduction to the exercise
67
+ - "instructions": detailed step-by-step instructions
68
+ - "interactive_components": list of interactive elements
69
+ - "materials_needed": required materials or resources
70
+ - "estimated_time": estimated completion time in minutes
71
+ - "difficulty_variations": easier and harder versions
72
+ - "assessment_rubric": criteria for evaluating student work
73
+ - "feedback_prompts": questions for self-reflection
74
+ - "extension_activities": additional challenges for advanced students
75
+ - "real_world_connections": how this relates to real-world applications
76
+ """
77
+
78
+ response = await MODEL.generate_text(prompt, temperature=0.7)
79
+ exercise_data = extract_json_from_text(response)
80
+
81
+ # Add metadata
82
+ exercise_data.update({
83
+ "success": True,
84
+ "concept": concept,
85
+ "exercise_type": exercise_type,
86
+ "difficulty_level": difficulty_level,
87
+ "student_level": student_level,
88
+ "generated_at": datetime.utcnow().isoformat(),
89
+ "ai_generated": True
90
+ })
91
+
92
+ return exercise_data
93
+
94
+ except Exception as e:
95
+ return {
96
+ "success": False,
97
+ "error": f"Failed to generate interactive exercise: {str(e)}"
98
+ }
99
+
100
+ @mcp.tool()
101
+ async def generate_adaptive_content_sequence(topic: str, student_profile: dict,
102
+ sequence_length: int = 5) -> dict:
103
+ """
104
+ Generate a sequence of adaptive content that adjusts based on student profile.
105
+
106
+ Args:
107
+ topic: Main topic for the content sequence
108
+ student_profile: Student's learning profile and preferences
109
+ sequence_length: Number of content pieces in the sequence
110
+
111
+ Returns:
112
+ Dictionary with adaptive content sequence
113
+ """
114
+ try:
115
+ prompt = f"""
116
+ Create an adaptive content sequence for the topic: "{topic}"
117
+
118
+ Student Profile:
119
+ {json.dumps(student_profile, indent=2)}
120
+
121
+ Generate a sequence of {sequence_length} interconnected content pieces that:
122
+ 1. Build upon each other progressively
123
+ 2. Adapt to the student's learning style and preferences
124
+ 3. Include multiple content types (text, visual descriptions, interactive elements)
125
+ 4. Provide branching paths based on understanding
126
+ 5. Include assessment checkpoints
127
+ 6. Offer remediation and enrichment options
128
+
129
+ Return JSON with:
130
+ - "sequence_id": unique identifier for the sequence
131
+ - "topic": main topic
132
+ - "total_pieces": number of content pieces
133
+ - "estimated_total_time": total estimated time in minutes
134
+ - "content_sequence": array of content pieces, each with:
135
+ - "piece_id": unique identifier
136
+ - "title": content title
137
+ - "content_type": type of content (explanation, example, practice, assessment)
138
+ - "content": main content text
139
+ - "visual_elements": descriptions of visual components
140
+ - "interactive_elements": interactive components
141
+ - "difficulty_level": difficulty rating
142
+ - "prerequisites": what student should know
143
+ - "learning_objectives": specific objectives for this piece
144
+ - "assessment_questions": questions to check understanding
145
+ - "branching_options": different paths based on performance
146
+ - "estimated_time": time for this piece
147
+ - "adaptation_rules": rules for how content adapts to student responses
148
+ - "success_criteria": criteria for successful completion
149
+ """
150
+
151
+ response = await MODEL.generate_text(prompt, temperature=0.6)
152
+ sequence_data = extract_json_from_text(response)
153
+
154
+ # Add metadata
155
+ sequence_data.update({
156
+ "success": True,
157
+ "topic": topic,
158
+ "student_profile": student_profile,
159
+ "generated_at": datetime.utcnow().isoformat(),
160
+ "ai_generated": True
161
+ })
162
+
163
+ return sequence_data
164
+
165
+ except Exception as e:
166
+ return {
167
+ "success": False,
168
+ "error": f"Failed to generate adaptive content sequence: {str(e)}"
169
+ }
170
+
171
+ @mcp.tool()
172
+ async def generate_scenario_based_learning(concept: str, scenario_type: str = "real_world",
173
+ complexity_level: str = "moderate") -> dict:
174
+ """
175
+ Generate scenario-based learning content with realistic situations.
176
+
177
+ Args:
178
+ concept: The concept to teach through scenarios
179
+ scenario_type: Type of scenario ('real_world', 'historical', 'futuristic', 'problem_solving')
180
+ complexity_level: Complexity of the scenario ('simple', 'moderate', 'complex')
181
+
182
+ Returns:
183
+ Dictionary with scenario-based learning content
184
+ """
185
+ try:
186
+ prompt = f"""
187
+ Create a {scenario_type} scenario-based learning experience for: "{concept}"
188
+
189
+ Scenario Parameters:
190
+ - Type: {scenario_type}
191
+ - Complexity: {complexity_level}
192
+
193
+ Design a realistic scenario that:
194
+ 1. Presents the concept in a meaningful context
195
+ 2. Requires students to apply their knowledge
196
+ 3. Includes decision points and consequences
197
+ 4. Provides multiple solution paths
198
+ 5. Connects to real-world applications
199
+ 6. Engages students emotionally and intellectually
200
+
201
+ Return JSON with:
202
+ - "scenario_id": unique identifier
203
+ - "title": compelling scenario title
204
+ - "setting": detailed description of the scenario setting
205
+ - "background_story": engaging background narrative
206
+ - "main_challenge": primary challenge students must solve
207
+ - "characters": key characters in the scenario (if applicable)
208
+ - "decision_points": critical decisions students must make
209
+ - "possible_outcomes": different outcomes based on decisions
210
+ - "learning_integration": how the concept is woven into the scenario
211
+ - "assessment_criteria": how to evaluate student responses
212
+ - "discussion_questions": questions for reflection and discussion
213
+ - "extension_scenarios": related scenarios for further exploration
214
+ - "real_world_connections": connections to actual situations
215
+ - "resources": additional resources students might need
216
+ """
217
+
218
+ response = await MODEL.generate_text(prompt, temperature=0.8)
219
+ scenario_data = extract_json_from_text(response)
220
+
221
+ # Add metadata
222
+ scenario_data.update({
223
+ "success": True,
224
+ "concept": concept,
225
+ "scenario_type": scenario_type,
226
+ "complexity_level": complexity_level,
227
+ "generated_at": datetime.utcnow().isoformat(),
228
+ "ai_generated": True
229
+ })
230
+
231
+ return scenario_data
232
+
233
+ except Exception as e:
234
+ return {
235
+ "success": False,
236
+ "error": f"Failed to generate scenario-based learning: {str(e)}"
237
+ }
238
+
239
+ @mcp.tool()
240
+ async def generate_multimodal_content(concept: str, modalities: List[str] = None,
241
+ target_audience: str = "general") -> dict:
242
+ """
243
+ Generate multi-modal content that appeals to different learning styles.
244
+
245
+ Args:
246
+ concept: The concept to create content for
247
+ modalities: List of modalities to include ('visual', 'auditory', 'kinesthetic', 'reading')
248
+ target_audience: Target audience description
249
+
250
+ Returns:
251
+ Dictionary with multi-modal content
252
+ """
253
+ try:
254
+ if not modalities:
255
+ modalities = ["visual", "auditory", "kinesthetic", "reading"]
256
+
257
+ prompt = f"""
258
+ Create multi-modal content for the concept: "{concept}"
259
+
260
+ Target Audience: {target_audience}
261
+ Modalities to include: {modalities}
262
+
263
+ Generate content that appeals to different learning styles:
264
+
265
+ Return JSON with:
266
+ - "content_id": unique identifier
267
+ - "concept": the main concept
268
+ - "visual_content": content for visual learners (descriptions of diagrams, charts, images)
269
+ - "auditory_content": content for auditory learners (descriptions of sounds, music, verbal explanations)
270
+ - "kinesthetic_content": content for kinesthetic learners (hands-on activities, movement, manipulation)
271
+ - "reading_content": content for reading/writing learners (text-based materials, written exercises)
272
+ - "integrated_activities": activities that combine multiple modalities
273
+ - "accessibility_features": features for students with different abilities
274
+ - "technology_integration": how technology can enhance each modality
275
+ - "assessment_variations": different ways to assess understanding for each modality
276
+ - "adaptation_guidelines": how to adapt content for different needs
277
+ """
278
+
279
+ response = await MODEL.generate_text(prompt, temperature=0.7)
280
+ content_data = extract_json_from_text(response)
281
+
282
+ # Add metadata
283
+ content_data.update({
284
+ "success": True,
285
+ "concept": concept,
286
+ "modalities": modalities,
287
+ "target_audience": target_audience,
288
+ "generated_at": datetime.utcnow().isoformat(),
289
+ "ai_generated": True
290
+ })
291
+
292
+ return content_data
293
+
294
+ except Exception as e:
295
+ return {
296
+ "success": False,
297
+ "error": f"Failed to generate multimodal content: {str(e)}"
298
+ }
299
+
300
+ @mcp.tool()
301
+ async def generate_adaptive_assessment(concept: str, assessment_type: str = "formative",
302
+ student_data: dict = None) -> dict:
303
+ """
304
+ Generate adaptive assessments that adjust based on student responses.
305
+
306
+ Args:
307
+ concept: The concept to assess
308
+ assessment_type: Type of assessment ('formative', 'summative', 'diagnostic', 'peer')
309
+ student_data: Optional student performance data
310
+
311
+ Returns:
312
+ Dictionary with adaptive assessment content
313
+ """
314
+ try:
315
+ prompt = f"""
316
+ Create an adaptive {assessment_type} assessment for: "{concept}"
317
+
318
+ Student Data: {json.dumps(student_data or {}, indent=2)}
319
+
320
+ Design an assessment that:
321
+ 1. Adapts difficulty based on student responses
322
+ 2. Provides immediate feedback
323
+ 3. Identifies learning gaps
324
+ 4. Offers multiple question types
325
+ 5. Includes branching logic
326
+ 6. Provides detailed analytics
327
+
328
+ Return JSON with:
329
+ - "assessment_id": unique identifier
330
+ - "title": assessment title
331
+ - "instructions": clear instructions for students
332
+ - "question_pool": large pool of questions with metadata:
333
+ - "question_id": unique identifier
334
+ - "question_text": the question
335
+ - "question_type": type (multiple_choice, short_answer, essay, etc.)
336
+ - "difficulty_level": difficulty rating (0.0 to 1.0)
337
+ - "cognitive_level": Bloom's taxonomy level
338
+ - "options": answer options (if applicable)
339
+ - "correct_answer": correct answer
340
+ - "explanation": detailed explanation
341
+ - "hints": progressive hints
342
+ - "common_misconceptions": common wrong answers and why
343
+ - "adaptive_rules": rules for question selection and difficulty adjustment
344
+ - "feedback_templates": templates for different types of feedback
345
+ - "scoring_rubric": detailed scoring criteria
346
+ - "analytics_tracking": what data to track for analysis
347
+ - "remediation_suggestions": suggestions based on performance
348
+ """
349
+
350
+ response = await MODEL.generate_text(prompt, temperature=0.6)
351
+ assessment_data = extract_json_from_text(response)
352
+
353
+ # Add metadata
354
+ assessment_data.update({
355
+ "success": True,
356
+ "concept": concept,
357
+ "assessment_type": assessment_type,
358
+ "generated_at": datetime.utcnow().isoformat(),
359
+ "ai_generated": True
360
+ })
361
+
362
+ return assessment_data
363
+
364
+ except Exception as e:
365
+ return {
366
+ "success": False,
367
+ "error": f"Failed to generate adaptive assessment: {str(e)}"
368
+ }
369
+
370
+ @mcp.tool()
371
+ async def generate_gamified_content(concept: str, game_type: str = "quest",
372
+ target_age_group: str = "teen") -> dict:
373
+ """
374
+ Generate gamified learning content with game mechanics and engagement features.
375
+
376
+ Args:
377
+ concept: The concept to gamify
378
+ game_type: Type of game ('quest', 'puzzle', 'simulation', 'competition', 'story')
379
+ target_age_group: Target age group ('child', 'teen', 'adult')
380
+
381
+ Returns:
382
+ Dictionary with gamified content
383
+ """
384
+ try:
385
+ prompt = f"""
386
+ Create gamified learning content for: "{concept}"
387
+
388
+ Game Parameters:
389
+ - Game Type: {game_type}
390
+ - Target Age Group: {target_age_group}
391
+
392
+ Design engaging game-based learning that includes:
393
+ 1. Clear game objectives aligned with learning goals
394
+ 2. Progressive difficulty levels
395
+ 3. Reward systems and achievements
396
+ 4. Interactive challenges
397
+ 5. Narrative elements (if applicable)
398
+ 6. Social features for collaboration/competition
399
+
400
+ Return JSON with:
401
+ - "game_id": unique identifier
402
+ - "title": engaging game title
403
+ - "theme": game theme and setting
404
+ - "storyline": narrative framework (if applicable)
405
+ - "learning_objectives": educational goals
406
+ - "game_mechanics": core game mechanics and rules
407
+ - "levels": progressive levels with increasing difficulty
408
+ - "challenges": specific challenges and tasks
409
+ - "reward_system": points, badges, achievements
410
+ - "character_progression": how players advance
411
+ - "social_features": multiplayer or collaborative elements
412
+ - "assessment_integration": how learning is assessed within the game
413
+ - "feedback_mechanisms": how players receive feedback
414
+ - "customization_options": ways to personalize the experience
415
+ - "accessibility_features": features for different abilities
416
+ """
417
+
418
+ response = await MODEL.generate_text(prompt, temperature=0.8)
419
+ game_data = extract_json_from_text(response)
420
+
421
+ # Add metadata
422
+ game_data.update({
423
+ "success": True,
424
+ "concept": concept,
425
+ "game_type": game_type,
426
+ "target_age_group": target_age_group,
427
+ "generated_at": datetime.utcnow().isoformat(),
428
+ "ai_generated": True
429
+ })
430
+
431
+ return game_data
432
+
433
+ except Exception as e:
434
+ return {
435
+ "success": False,
436
+ "error": f"Failed to generate gamified content: {str(e)}"
437
+ }
438
+
439
+ @mcp.tool()
440
+ async def validate_generated_content(content_data: dict, validation_criteria: dict = None) -> dict:
441
+ """
442
+ Validate and quality-check generated educational content.
443
+
444
+ Args:
445
+ content_data: The content to validate
446
+ validation_criteria: Specific criteria for validation
447
+
448
+ Returns:
449
+ Dictionary with validation results and suggestions
450
+ """
451
+ try:
452
+ default_criteria = {
453
+ "educational_alignment": True,
454
+ "age_appropriateness": True,
455
+ "clarity": True,
456
+ "engagement": True,
457
+ "accessibility": True,
458
+ "accuracy": True
459
+ }
460
+
461
+ criteria = {**default_criteria, **(validation_criteria or {})}
462
+
463
+ prompt = f"""
464
+ Validate this educational content against quality criteria:
465
+
466
+ Content to Validate:
467
+ {json.dumps(content_data, indent=2)}
468
+
469
+ Validation Criteria:
470
+ {json.dumps(criteria, indent=2)}
471
+
472
+ Perform comprehensive validation and return JSON with:
473
+ - "overall_quality_score": score from 0.0 to 1.0
474
+ - "validation_results": detailed results for each criterion
475
+ - "strengths": identified strengths in the content
476
+ - "areas_for_improvement": specific areas that need work
477
+ - "suggestions": concrete suggestions for improvement
478
+ - "compliance_check": compliance with educational standards
479
+ - "accessibility_assessment": accessibility for different learners
480
+ - "engagement_analysis": analysis of engagement potential
481
+ - "accuracy_verification": verification of factual accuracy
482
+ - "recommended_modifications": specific modifications to make
483
+ """
484
+
485
+ response = await MODEL.generate_text(prompt, temperature=0.3)
486
+ validation_data = extract_json_from_text(response)
487
+
488
+ return {
489
+ "success": True,
490
+ "content_validated": True,
491
+ "validation_timestamp": datetime.utcnow().isoformat(),
492
+ **validation_data
493
+ }
494
+
495
+ except Exception as e:
496
+ return {
497
+ "success": False,
498
+ "error": f"Failed to validate content: {str(e)}"
499
+ }
tests/test_ai_integration.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script for the new AI integration features in TutorX-MCP.
4
+ Tests the contextualized AI tutoring and automated content generation.
5
+ """
6
+
7
+ import asyncio
8
+ import json
9
+ import sys
10
+ import os
11
+
12
+ # Add the current directory to the Python path
13
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
14
+
15
+ from mcp_server.tools.ai_tutor_tools import (
16
+ start_tutoring_session,
17
+ ai_tutor_chat,
18
+ get_step_by_step_guidance,
19
+ get_alternative_explanations,
20
+ end_tutoring_session
21
+ )
22
+
23
+ from mcp_server.tools.content_generation_tools import (
24
+ generate_interactive_exercise,
25
+ generate_scenario_based_learning,
26
+ generate_gamified_content
27
+ )
28
+
29
+ async def test_ai_tutoring():
30
+ """Test the AI tutoring functionality"""
31
+ print("🤖 Testing AI Tutoring Features...")
32
+
33
+ # Test 1: Start a tutoring session
34
+ print("\n1. Starting tutoring session...")
35
+ session_result = await start_tutoring_session(
36
+ student_id="test_student_001",
37
+ subject="Mathematics",
38
+ learning_objectives=["Understand quadratic equations", "Learn factoring methods"]
39
+ )
40
+ print(f"Session started: {session_result.get('success', False)}")
41
+
42
+ if not session_result.get('success'):
43
+ print(f"❌ Failed to start session: {session_result.get('error')}")
44
+ return
45
+
46
+ session_id = session_result.get('session_id')
47
+ print(f"Session ID: {session_id}")
48
+
49
+ # Test 2: Chat with AI tutor
50
+ print("\n2. Chatting with AI tutor...")
51
+ chat_result = await ai_tutor_chat(
52
+ session_id=session_id,
53
+ student_query="How do I solve quadratic equations?",
54
+ request_type="explanation"
55
+ )
56
+ print(f"Chat response received: {chat_result.get('success', False)}")
57
+
58
+ # Test 3: Get step-by-step guidance
59
+ print("\n3. Getting step-by-step guidance...")
60
+ steps_result = await get_step_by_step_guidance(
61
+ session_id=session_id,
62
+ concept="Solving quadratic equations",
63
+ current_step=1
64
+ )
65
+ print(f"Step-by-step guidance received: {steps_result.get('success', False)}")
66
+
67
+ # Test 4: Get alternative explanations
68
+ print("\n4. Getting alternative explanations...")
69
+ alt_result = await get_alternative_explanations(
70
+ session_id=session_id,
71
+ concept="Quadratic formula",
72
+ explanation_types=["visual", "analogy", "real_world"]
73
+ )
74
+ print(f"Alternative explanations received: {alt_result.get('success', False)}")
75
+
76
+ # Test 5: End session
77
+ print("\n5. Ending tutoring session...")
78
+ end_result = await end_tutoring_session(
79
+ session_id=session_id,
80
+ session_summary="Learned about quadratic equations and different solving methods"
81
+ )
82
+ print(f"Session ended: {end_result.get('success', False)}")
83
+
84
+ print("✅ AI Tutoring tests completed!")
85
+
86
+ async def test_content_generation():
87
+ """Test the content generation functionality"""
88
+ print("\n🎨 Testing Content Generation Features...")
89
+
90
+ # Test 1: Generate interactive exercise
91
+ print("\n1. Generating interactive exercise...")
92
+ exercise_result = await generate_interactive_exercise(
93
+ concept="Photosynthesis",
94
+ exercise_type="simulation",
95
+ difficulty_level=0.6,
96
+ student_level="intermediate"
97
+ )
98
+ print(f"Interactive exercise generated: {exercise_result.get('success', False)}")
99
+
100
+ # Test 2: Generate scenario-based learning
101
+ print("\n2. Generating scenario-based learning...")
102
+ scenario_result = await generate_scenario_based_learning(
103
+ concept="Climate Change",
104
+ scenario_type="real_world",
105
+ complexity_level="moderate"
106
+ )
107
+ print(f"Scenario-based learning generated: {scenario_result.get('success', False)}")
108
+
109
+ # Test 3: Generate gamified content
110
+ print("\n3. Generating gamified content...")
111
+ game_result = await generate_gamified_content(
112
+ concept="Fractions",
113
+ game_type="quest",
114
+ target_age_group="teen"
115
+ )
116
+ print(f"Gamified content generated: {game_result.get('success', False)}")
117
+
118
+ print("✅ Content Generation tests completed!")
119
+
120
+ async def main():
121
+ """Run all tests"""
122
+ print("🚀 Starting TutorX AI Integration Tests...")
123
+ print("=" * 50)
124
+
125
+ try:
126
+ # Test AI Tutoring
127
+ await test_ai_tutoring()
128
+
129
+ # Test Content Generation
130
+ await test_content_generation()
131
+
132
+ print("\n" + "=" * 50)
133
+ print("🎉 All tests completed successfully!")
134
+
135
+ except Exception as e:
136
+ print(f"\n❌ Test failed with error: {str(e)}")
137
+ import traceback
138
+ traceback.print_exc()
139
+
140
+ if __name__ == "__main__":
141
+ asyncio.run(main())