DarainHyder
Initial clean deploy commit: removing binary files and venv
25732fb
"""
Teaching Agent - Autonomous content generation and delivery
"""
import json
from .base_agent import BaseAgent
from llm_service import LLMService
from agent_knowledge.rules.teaching_rules import TeachingRuleEngine
from agent_communication.message_bus import AgentMessageBus
from agent_communication.protocols import MessageProtocols
from datetime import datetime
import random
class TeachingAgent(BaseAgent):
"""
Autonomous agent responsible for:
- Generating personalized lessons
- Adapting teaching style
- Selecting examples based on student performance
"""
def __init__(self):
super().__init__("TA-001", "TeachingAgent")
self.llm_service = LLMService()
self.rule_engine = TeachingRuleEngine()
self.message_bus = AgentMessageBus()
self.lessons_generated = 0
self.knowledge_level = 0.0
self.learning_style = "visual"
self.lesson_complexity = "beginner"
self.current_strategy = {}
def perceive(self, student_state):
self.update_state("perceiving")
self.log(f"Perceiving student state for user {student_state.user_id}")
# Update internal state based on student data
self.user_id = student_state.user_id
self.knowledge_level = student_state.knowledge_level
self.learning_style = student_state.learning_style or "visual"
# Determine lesson complexity based on knowledge level
if self.knowledge_level < 0.3:
self.lesson_complexity = "beginner"
elif self.knowledge_level < 0.7:
self.lesson_complexity = "intermediate"
else:
self.lesson_complexity = "advanced"
self.update_state("perceived")
return self.state
def decide(self):
self.update_state("deciding")
# Use rule engine to determine strategy
student_profile = {
"knowledge_level": self.knowledge_level,
"learning_style": self.learning_style,
# Mock recent performance for now, ideally comes from KnowledgeAgent
"recent_performance": 0.8
}
self.current_strategy = self.rule_engine.select_teaching_strategy(student_profile)
self.log(f"Selected teaching strategy: {self.current_strategy['name']}")
self.update_state("decided")
return self
def act(self, topic, prompt=None):
self.update_state("acting")
self.log(f"Generating lesson for topic: {topic.name} with strategy {self.current_strategy['name']}")
# 1. Request updated profile from KnowledgeAgent (Async/Simulated)
self.message_bus.send_message(
self.name,
"KnowledgeAgent",
MessageProtocols.KNOWLEDGE_REQUEST,
MessageProtocols.request_student_profile(self.user_id, topic.id)
)
try:
# 2. Generate Lesson Structure using Rule Engine (No LLM)
lesson_structure = self.rule_engine.generate_lesson_structure(topic, self.current_strategy)
# 3. Fill in content (Hybrid: Try Templates first, else Fallback to LLM for specific sections)
# For this MVP, we will use the structure to guide the LLM, reducing its "thinking" time
# In a full impl, we would pull pre-written content from ContentLibrary
structured_prompt = f"""
Create a lesson for topic '{topic.name}' ({topic.difficulty}) following this structure:
Strategy: {self.current_strategy['name']} ({self.current_strategy['description']})
Sections:
"""
for section in lesson_structure['sections']:
structured_prompt += f"\n- {section['title']}: {section['instruction_for_llm']}"
# Fallback to LLM for content generation but with strict structure
lesson_content = self.llm_service.generate_lesson_with_prompt(
topic.name,
topic.difficulty,
self.knowledge_level,
custom_prompt=structured_prompt
)
self.lessons_generated += 1
self.log(f"Lesson generated successfully using rule-guided structure. (Total: {self.lessons_generated})")
# Store in agent memory
self.memory.append({
"action": "lesson_generated",
"topic": topic.name,
"strategy": self.current_strategy['name'],
"complexity": self.lesson_complexity,
"user_id": self.user_id
})
self.update_state("completed")
return {
"content": lesson_content,
"metadata": {
"teaching_style": self.current_strategy.get('name', 'default'),
"complexity": self.lesson_complexity,
"example_count": self.current_strategy.get('example_count', 3),
"agent": self.name,
"generated_at": datetime.utcnow().isoformat()
}
}
except Exception as e:
self.log(f"Error generating lesson: {str(e)}", "error")
self.update_state("error")
return {"error": str(e)}
def get_statistics(self):
"""Return agent statistics"""
return {
"agent": self.name,
"lessons_generated": self.lessons_generated,
"current_style": self.current_style,
"state": self.state,
"memory_size": len(self.memory)
}