"""GPTZero AI content detection service.""" import logging import time _logger = logging.getLogger(__name__) try: import requests as _requests except ImportError: _requests = None GPTZERO_BASE = "https://api.gptzero.me/v2" class GPTZeroService: """Detect AI-generated content in student submissions.""" def __init__(self, env): self.env = env self._get_param = env["ir.config_parameter"].sudo().get_param def _get_key(self): key = self._get_param("encoach_ai.gptzero_api_key", "") if not key: import os key = os.environ.get("GPT_ZERO_API_KEY", "") if not key: raise RuntimeError("GPTZero API key not configured — set in AI Settings") return key def _log(self, action, latency, status="success", error=None): try: self.env["encoach.ai.log"].sudo().create({ "service": "gptzero", "action": action, "latency_ms": latency, "status": status, "error_message": error, }) except Exception: pass def detect(self, text): """Check if text is AI-generated. Returns: dict with 'is_ai_generated' (bool), 'ai_probability' (float 0-1), 'human_probability' (float), 'sentences' (list of per-sentence scores) """ if not _requests: raise RuntimeError("requests package not installed") key = self._get_key() t0 = time.time() try: resp = _requests.post( f"{GPTZERO_BASE}/predict/text", json={"document": text}, headers={"x-api-key": key, "Content-Type": "application/json"}, timeout=30, ) resp.raise_for_status() data = resp.json() doc = data.get("documents", [{}])[0] if data.get("documents") else {} result = { "is_ai_generated": doc.get("completely_generated_prob", 0) > 0.5, "ai_probability": doc.get("completely_generated_prob", 0), "human_probability": 1 - doc.get("completely_generated_prob", 0), "mixed_probability": doc.get("average_generated_prob", 0), "sentences": [ { "text": s.get("sentence", ""), "ai_probability": s.get("generated_prob", 0), "is_ai": s.get("generated_prob", 0) > 0.5, } for s in doc.get("sentences", []) ], } self._log("detect", int((time.time() - t0) * 1000)) return result except Exception as exc: self._log("detect", int((time.time() - t0) * 1000), "error", str(exc)) raise def detect_batch(self, texts): """Check multiple texts for AI generation.""" return [self.detect(t) for t in texts]