File size: 2,098 Bytes
07a91a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""Simple hallucination checks for generated code."""

from __future__ import annotations

import ast
import subprocess
import sys
import tempfile
from dataclasses import dataclass


@dataclass
class HallucinationCheckResult:
    hallucination: bool
    reason: str


def _python_syntax_check(code: str) -> HallucinationCheckResult:
    try:
        ast.parse(code)
        return HallucinationCheckResult(False, "Syntax is valid.")
    except SyntaxError as exc:
        return HallucinationCheckResult(True, f"Syntax error: {exc}")


def _python_runtime_smoke_test(code: str) -> HallucinationCheckResult:
    try:
        with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False, encoding="utf-8") as tmp:
            tmp.write(code)
            tmp_path = tmp.name
        proc = subprocess.run(
            [sys.executable, tmp_path],
            capture_output=True,
            text=True,
            timeout=4,
            check=False,
        )
        if proc.returncode != 0:
            stderr = proc.stderr.strip()[:300]
            return HallucinationCheckResult(True, f"Runtime test failed: {stderr}")
        return HallucinationCheckResult(False, "Runtime smoke test passed.")
    except subprocess.TimeoutExpired:
        return HallucinationCheckResult(True, "Runtime test timed out.")
    except Exception as exc:  # pragma: no cover
        return HallucinationCheckResult(True, f"Runtime test error: {exc}")


def hallucination_check(code: str) -> HallucinationCheckResult:
    """Run syntax and runtime checks and consolidate status."""
    # Skip expensive/irrelevant execution for obviously non-Python snippets.
    python_hints = ("def ", "class ", "import ", "from ", "print(", "if __name__")
    if not any(hint in code for hint in python_hints):
        return HallucinationCheckResult(False, "Skipped runtime check for non-Python-like output.")

    syntax_result = _python_syntax_check(code)
    if syntax_result.hallucination:
        return syntax_result
    return _python_runtime_smoke_test(code)