Spaces:
Running
Running
| """ | |
| CodeMentor Pro - Multi-type Error Detection | |
| Now routes Python, JavaScript, C++, and Java through REAL execution: | |
| - Python -> local subprocess sandbox (default; set | |
| config.PYTHON_EXECUTION_ENGINE=judge0 to route it through Judge0 too) | |
| - JavaScript/C++/Java -> Judge0 (real compile/interpret + execute) | |
| Whenever a real engine can't be used for a given submission (Judge0 down, | |
| rate-limited, or no engine mapped for the language) we transparently fall | |
| back to the same LLM static-estimate prompt used before, so the app never | |
| just fails a submission outright - it degrades honestly instead. | |
| """ | |
| from sandbox import execute_code | |
| from store import record_submission, get_weakness_note | |
| from llm import call_groq_json | |
| from prompts import LOGICAL_ERROR_PROMPT, STATIC_ANALYSIS_PROMPT | |
| def _run_static_estimate(code: str, language: str) -> dict: | |
| """LLM-based fallback when no real execution happened for this submission.""" | |
| out = { | |
| "syntax": {"found": False, "message": ""}, | |
| "runtime": {"found": False, "message": ""}, | |
| "tle": {"found": False, "message": "", "runtime_seconds": None}, | |
| "syntax_err": False, | |
| "tle_err": False, | |
| } | |
| try: | |
| static_result = call_groq_json(STATIC_ANALYSIS_PROMPT, f"Language: {language}\n\nCode:\n{code}") | |
| except Exception as e: | |
| out["syntax"]["message"] = f"{language} static analysis unavailable: {e}" | |
| return out | |
| if static_result.get("syntax_error_found"): | |
| out["syntax"] = { | |
| "found": True, | |
| "message": static_result.get( | |
| "syntax_error_message", "Potential syntax issue detected (unverified β static estimate)." | |
| ), | |
| } | |
| out["syntax_err"] = True | |
| else: | |
| out["syntax"]["message"] = ( | |
| f"No obvious syntax issues found for {language} " | |
| "(unverified β static LLM estimate, not real execution)." | |
| ) | |
| if static_result.get("runtime_error_found"): | |
| out["runtime"] = {"found": True, "message": static_result.get("runtime_error_message", "")} | |
| if static_result.get("tle_risk_found"): | |
| out["tle"] = { | |
| "found": True, | |
| "message": static_result.get( | |
| "tle_risk_message", "Potential performance risk (unverified β static estimate)." | |
| ), | |
| "runtime_seconds": None, | |
| } | |
| out["tle_err"] = True | |
| return out | |
| def detect_errors(code: str, language: str) -> dict: | |
| result = { | |
| "syntax": {"found": False, "message": ""}, | |
| "runtime": {"found": False, "message": ""}, | |
| "tle": {"found": False, "message": "", "runtime_seconds": None}, | |
| "logical": {"found": False, "issues": []}, | |
| "weakness_note": "", | |
| "verified_by_execution": False, | |
| } | |
| syntax_err = False | |
| tle_err = False | |
| exec_result = execute_code(code, language) | |
| if not exec_result.engine_failure: | |
| # Real execution happened - Python (local) or C++/Java (Judge0). | |
| result["verified_by_execution"] = True | |
| result["tle"]["runtime_seconds"] = exec_result.runtime_seconds | |
| if exec_result.error_type == "syntax": | |
| result["syntax"] = {"found": True, "message": exec_result.error_message} | |
| syntax_err = True | |
| elif exec_result.error_type == "runtime": | |
| result["runtime"] = {"found": True, "message": exec_result.error_message} | |
| elif exec_result.error_type == "tle": | |
| result["tle"] = { | |
| "found": True, | |
| "message": exec_result.error_message, | |
| "runtime_seconds": exec_result.runtime_seconds, | |
| } | |
| tle_err = True | |
| else: | |
| # No engine available for this submission (unmapped language, or a | |
| # live Judge0 failure) - fall back to the LLM static estimate. | |
| static = _run_static_estimate(code, language) | |
| result["syntax"] = static["syntax"] | |
| result["runtime"] = static["runtime"] | |
| result["tle"] = static["tle"] | |
| syntax_err = static["syntax_err"] | |
| tle_err = static["tle_err"] | |
| if language in ("python", "javascript", "cpp", "java"): | |
| # This language normally HAS a real engine, so engine_failure here | |
| # means Judge0 failed just for this run - worth surfacing clearly | |
| # rather than silently looking identical to "no engine exists". | |
| result["syntax"]["message"] = ( | |
| f"β οΈ Real execution unavailable this run ({exec_result.error_message}) β " | |
| f"showing an unverified static estimate instead. {result['syntax']['message']}" | |
| ) | |
| logical_err = False | |
| if not syntax_err: | |
| try: | |
| llm_result = call_groq_json(LOGICAL_ERROR_PROMPT, f"Language: {language}\n\nCode:\n{code}") | |
| if llm_result.get("logical_errors_found"): | |
| logical_err = True | |
| result["logical"] = {"found": True, "issues": llm_result.get("issues", [])} | |
| except Exception as e: | |
| result["logical"] = {"found": False, "issues": [], "error": str(e)} | |
| record_submission(language, code, syntax_error=syntax_err, logical_error=logical_err, tle=tle_err) | |
| result["weakness_note"] = get_weakness_note(language) | |
| return result |