diff --git a/custom_addons/encoach_ai/controllers/ai_controller.py b/custom_addons/encoach_ai/controllers/ai_controller.py index 7f41dbcf..32cf790a 100644 --- a/custom_addons/encoach_ai/controllers/ai_controller.py +++ b/custom_addons/encoach_ai/controllers/ai_controller.py @@ -409,14 +409,41 @@ class AIController(http.Controller): def _generate_exercises(self, ai, module, body): passage_text = body.get("passage_text", "") exercise_types = body.get("exercise_types", []) - count = body.get("count_per_type", 5) - types_str = ", ".join(exercise_types) if exercise_types else "multiple choice" + type_counts = body.get("type_counts", {}) + type_instructions = body.get("type_instructions", {}) + default_count = body.get("count_per_type", 5) + difficulty = body.get("difficulty", "B2") + + type_specs = [] + total = 0 + for et in exercise_types: + c = int(type_counts.get(et, default_count)) + instr = type_instructions.get(et, "") + spec_line = f"- EXACTLY {c} questions of type \"{et}\"" + if instr: + spec_line += f"\n Student instructions: \"{instr}\"" + type_specs.append(spec_line) + total += c + spec_str = "\n".join(type_specs) if type_specs else f"- {default_count} multiple choice questions" + messages = [ {"role": "system", "content": ( - f"Based on the following text, generate {count} exercises of these types: {types_str}. " - "Return JSON: " - '{"questions": [{"type": string, "prompt": string, "options": [string], ' - '"correct_answer": string, "explanation": string, "marks": number}]}' + f"You are an exam question generator. Generate EXACTLY {total} exercises " + f"at CEFR {difficulty} level based on the passage below.\n\n" + f"REQUIRED question breakdown (you MUST follow these counts exactly):\n" + f"{spec_str}\n\n" + "CRITICAL RULES:\n" + f"1. The total number of questions in your response MUST be exactly {total}.\n" + "2. Each question MUST have a 'type' field set to one of the requested types.\n" + "3. Each question MUST include an 'instructions' field with the student-facing instructions " + "for that section (use the provided instructions, or write appropriate ones).\n" + "4. For mcq/true_false types: include 'options' array and 'correct_answer'.\n" + "5. For fill_blanks/write_blanks types: use '___' in the prompt for blanks, " + "set correct_answer to the missing word(s), options can be empty.\n" + "6. For paragraph_match: prompt describes what to match, options are paragraph labels.\n\n" + "Return JSON:\n" + '{"questions": [{"type": string, "instructions": string, "prompt": string, ' + '"options": [string], "correct_answer": string, "explanation": string, "marks": number}]}' )}, {"role": "user", "content": passage_text[:3000]}, ]