from typing import List from openai import OpenAI from learning_objective_generator import LearningObjectiveGenerator from learning_objective_generator.grouping_and_ranking import group_base_learning_objectives from .question_generation import generate_multiple_choice_question from .question_improvement import ( should_regenerate_incorrect_answers, regenerate_incorrect_answers, judge_question_quality ) from .question_ranking import rank_questions, group_questions from .feedback_questions import generate_multiple_choice_question_from_feedback from .assessment import generate_assessment, generate_questions_in_parallel, save_assessment_to_json class QuizGenerator: """Simple orchestrator for quiz generation.""" def __init__(self, api_key: str, model: str = "gpt-5", temperature: float = 1.0): self.client = OpenAI(api_key=api_key) self.model = model self.temperature = temperature self.learning_objective_generator = LearningObjectiveGenerator( api_key=api_key, model=model, temperature=temperature ) def generate_base_learning_objectives(self, file_contents: List[str], num_objectives: int, incorrect_answer_model: str = None): """Generate only base learning objectives (no grouping, no incorrect answers). This allows the UI to collect objectives from multiple runs before grouping.""" return self.learning_objective_generator.generate_base_learning_objectives( file_contents, num_objectives ) def generate_lo_incorrect_answer_options(self, file_contents, base_objectives, model_override=None): """Generate incorrect answer options for the given base learning objectives (wrapper for LearningObjectiveGenerator).""" return self.learning_objective_generator.generate_incorrect_answer_options( file_contents, base_objectives, model_override ) def group_base_learning_objectives(self, base_learning_objectives, file_contents: List[str]): """Group base learning objectives and identify best in group.""" return group_base_learning_objectives( self.client, self.model, self.temperature, base_learning_objectives, file_contents ) def generate_multiple_choice_question(self, learning_objective, file_contents: List[str]): return generate_multiple_choice_question( self.client, self.model, self.temperature, learning_objective, file_contents ) def should_regenerate_incorrect_answers(self, question, file_contents: List[str], model_name: str = "gpt-5-mini"): return should_regenerate_incorrect_answers( self.client, question, file_contents, model_name ) def regenerate_incorrect_answers(self, questions, file_contents: List[str]): return regenerate_incorrect_answers( self.client, self.model, self.temperature, questions, file_contents ) def rank_questions(self, questions, file_contents: List[str]): return rank_questions( self.client, self.model, self.temperature, questions, file_contents ) def group_questions(self, questions, file_contents: List[str]): return group_questions( self.client, self.model, self.temperature, questions, file_contents ) def generate_multiple_choice_question_from_feedback(self, feedback: str, file_contents: List[str]): return generate_multiple_choice_question_from_feedback( self.client, self.model, self.temperature, feedback, file_contents ) def judge_question_quality(self, question): return judge_question_quality( self.client, self.model, self.temperature, question ) def generate_assessment(self, file_contents: List[str], num_objectives: int): return generate_assessment( self.client, self.model, self.temperature, self.learning_objective_generator, file_contents, num_objectives ) def generate_questions_in_parallel(self, learning_objectives, file_contents: List[str]): return generate_questions_in_parallel( self.client, self.model, self.temperature, learning_objectives, file_contents ) def save_assessment_to_json(self, assessment, output_path: str): return save_assessment_to_json(assessment, output_path)