clinical-mind / backend /app /models /simulation.py
arjitmat's picture
feat: Complete Clinical-Mind v2.0 - Full-Stack AI Patient Simulator
69832ef
"""Data models for AI Patient Simulation."""
from datetime import datetime
from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, Field
class EmotionalState(str, Enum):
"""Patient emotional states."""
CALM = "calm"
CONCERNED = "concerned"
ANXIOUS = "anxious"
DEFENSIVE = "defensive"
class PatientGender(str, Enum):
"""Patient gender categories for avatar selection."""
MALE = "male"
FEMALE = "female"
PREGNANT = "pregnant"
class RapportLevel(int, Enum):
"""Rapport level between student and patient (1-5 scale)."""
VERY_LOW = 1
LOW = 2
MODERATE = 3
GOOD = 4
EXCELLENT = 5
class FeedbackType(str, Enum):
"""Types of AI tutor feedback."""
POSITIVE = "positive" # ✓ green
WARNING = "warning" # ⚠️ amber
CRITICAL = "critical" # ✗ red
class PatientProfile(BaseModel):
"""Patient demographic and clinical profile."""
age: int
gender: PatientGender
name: str
chief_complaint: str
setting: str # "ER", "OPD", "ward", etc.
specialty: str
difficulty: str # "beginner", "intermediate", "advanced"
# Hidden diagnosis (not shown to student)
actual_diagnosis: str
key_history_points: List[str]
physical_exam_findings: dict
# Initial state
initial_emotional_state: EmotionalState = EmotionalState.CONCERNED
class SimulationMessage(BaseModel):
"""A message in the patient-student conversation."""
role: str # "student" or "patient"
content: str
timestamp: datetime = Field(default_factory=datetime.now)
emotional_state: Optional[EmotionalState] = None # Only for patient messages
class TutorFeedback(BaseModel):
"""Real-time feedback from AI tutor."""
type: FeedbackType
message: str
timestamp: datetime = Field(default_factory=datetime.now)
class EvaluationMetrics(BaseModel):
"""Evaluation metrics for student communication."""
empathy_score: int # 1-5
communication_quality: int # 1-5
clinical_reasoning: int # 1-5
open_ended_questions: int # count
acknowledged_distress: bool
bedside_manner: int # 1-5
class SimulationState(BaseModel):
"""Complete state of an active simulation."""
case_id: str
patient_profile: PatientProfile
# Current state
emotional_state: EmotionalState
rapport_level: RapportLevel
# Conversation history
messages: List[SimulationMessage] = []
tutor_feedback: List[TutorFeedback] = []
# Evaluation
evaluation: Optional[EvaluationMetrics] = None
# Metadata
started_at: datetime = Field(default_factory=datetime.now)
completed_at: Optional[datetime] = None
student_diagnosis: Optional[str] = None
student_reasoning: Optional[str] = None
# === API Request/Response Models ===
class StartSimulationRequest(BaseModel):
"""Request to start a new simulation."""
specialty: str = "general_medicine"
difficulty: str = "intermediate"
year_level: str = "final_year" # for future use
class StartSimulationResponse(BaseModel):
"""Response when starting a simulation."""
case_id: str
patient_info: dict # Safe patient info (no diagnosis)
avatar_path: str # e.g., "/avatars/male/concerned.svg"
setting_context: str
initial_message: str # Patient's first words
class SendMessageRequest(BaseModel):
"""Student sending a message to the patient."""
case_id: str
student_message: str
class SendMessageResponse(BaseModel):
"""Patient response + state updates + tutor feedback."""
patient_response: str
emotional_state: EmotionalState
rapport_level: RapportLevel
tutor_feedback: List[TutorFeedback]
avatar_path: str # May change based on emotional state
class CompleteSimulationRequest(BaseModel):
"""Student completing the simulation with diagnosis."""
case_id: str
diagnosis: str
reasoning: str
class CognitiveAutopsy(BaseModel):
"""Deep analysis of student's diagnostic process."""
mental_model: str
breaking_point: str # When/where reasoning broke down
what_you_missed: List[str]
why_you_missed_it: str
pattern_across_cases: Optional[str] = None
prediction: str # What they'll likely miss in future
class CompleteSimulationResponse(BaseModel):
"""Response after simulation completion."""
correct_diagnosis: str
diagnosis_correct: bool
cognitive_autopsy: CognitiveAutopsy
evaluation: EvaluationMetrics