ecuartasm's picture
Initial commit: AI Course Assessment Generator
217abc3
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)