from typing import List, Optional, Union from pydantic import BaseModel, Field class BaseLearningObjectiveWithoutCorrectAnswer(BaseModel): """Model for a learning objective without a correct answer.""" id: int = Field(description="Unique identifier for the learning objective") learning_objective: str = Field(description="Description of the learning objective") source_reference: Union[List[str], str] = Field(description="Paths to the files from which this learning objective was extracted") class BaseLearningObjective(BaseModel): """Model for a learning objective.""" id: int = Field(description="Unique identifier for the learning objective") learning_objective: str = Field(description="Description of the learning objective") source_reference: Union[List[str], str] = Field(description="Paths to the files from which this learning objective was extracted") correct_answer: str = Field(description="Correct answer to the learning objective") class LearningObjective(BaseModel): """Model for a learning objective.""" id: int = Field(description="Unique identifier for the learning objective") learning_objective: str = Field(description="Description of the learning objective") source_reference: Union[List[str], str] = Field(description="Paths to the files from which this learning objective was extracted") correct_answer: str = Field(description="Correct answer to the learning objective") incorrect_answer_options: Union[List[str], str] = Field(description="A list of five incorrect answer options") in_group: Optional[bool] = Field(default=None, description="Whether this objective is part of a group") group_members: Optional[List[int]] = Field(default=None, description="List of IDs of objectives in the same group") best_in_group: Optional[bool] = Field(default=None, description="Whether this is the best objective in its group") class GroupedLearningObjective(LearningObjective): """Model for a learning objective that has been grouped.""" in_group: bool = Field(description="Whether this objective is part of a group of similar objectives") group_members: List[int] = Field(description="List of IDs of all objectives in the same similarity group, including this one") best_in_group: bool = Field(description="True if this objective is the highest ranked in its group") class GroupedBaseLearningObjective(BaseLearningObjective): """Model for a base learning objective that has been grouped (without incorrect answer suggestions).""" in_group: bool = Field(description="Whether this objective is part of a group of similar objectives") group_members: List[int] = Field(description="List of IDs of all objectives in the same similarity group, including this one") best_in_group: bool = Field(description="True if this objective is the highest ranked in its group") # Response models for learning objectives class BaseLearningObjectivesWithoutCorrectAnswerResponse(BaseModel): objectives: List[BaseLearningObjectiveWithoutCorrectAnswer] = Field(description="List of learning objectives without correct answers") class LearningObjectivesResponse(BaseModel): objectives: List[LearningObjective] = Field(description="List of learning objectives") class GroupedLearningObjectivesResponse(BaseModel): grouped_objectives: List[GroupedLearningObjective] = Field(description="List of grouped learning objectives") class GroupedBaseLearningObjectivesResponse(BaseModel): grouped_objectives: List[GroupedBaseLearningObjective] = Field(description="List of grouped base learning objectives")