from __future__ import annotations from app.schemas.cross_validation import AnswerKind, TaskType from app.schemas.numeric import NumericCheckItem from app.schemas.pedagogy import PedagogicalContext from app.services.cross_validation_numeric_adapter import cross_validation_report_to_numeric_check from app.services.math_cross_validation_orchestrator import run_cross_validation_with_wolfram_reference from app.services.math_llm_cross_validation import solve_exercise_independently_with_llm, translate_exercise_to_wolfram_with_llm async def run_solution_set_cross_validation_numeric_check( *, answer_text: str, pedagogical_context: PedagogicalContext, ) -> NumericCheckItem: expected_kind = AnswerKind.SOLUTION_SET wolfram_candidate = await translate_exercise_to_wolfram_with_llm( pedagogical_context=pedagogical_context, expected_answer_kind=expected_kind, ) candidate_kind = getattr(wolfram_candidate, "expected_answer_kind", expected_kind) candidate_task = getattr(wolfram_candidate, "task_type", TaskType.EQUATION) if candidate_kind != expected_kind or candidate_task != TaskType.EQUATION: actual_kind = getattr(candidate_kind, "value", str(candidate_kind)) actual_task = getattr(candidate_task, "value", str(candidate_task)) return NumericCheckItem( check_type="equivalence", expression="cross_validation_skipped", expected=expected_kind.value, is_valid=True, details=f"cross_validation_skipped_incompatible_task={actual_task}; answer_kind={actual_kind}", sympy_status="skipped", wolfram_status="skipped", cas_status="NO_CAS_VALIDATION", preferred_engine="none", confidence_impact="neutral", human_review_reason=None, ) llm_answer = await solve_exercise_independently_with_llm( pedagogical_context=pedagogical_context, expected_answer_kind=expected_kind, ) report = await run_cross_validation_with_wolfram_reference( answer_text=answer_text, expected_answer_kind=expected_kind, llm_answer=llm_answer, wolfram_query=wolfram_candidate.wolfram_query, ) return cross_validation_report_to_numeric_check(report)