from typing import Any, Dict, List from app.config import settings def _build_rule_suggestions(verdict: str, indicators: List[str], word_count: int) -> List[str]: verdict = verdict.upper() suggestions: List[str] = [] if verdict in ("AI GENERATED", "LIKELY AI"): suggestions = [ "Add personal anecdotes, first-person details, and real-world context to break the synthetic pattern.", "Vary sentence length and structure to avoid uniform AI-style rhythm.", "Use conversational phrasing, contractions, and less formal wording.", "Introduce subtle human emotion, sensory detail, or a personal opinion to make the writing feel more authentic." ] if any("Low perplexity" in ind for ind in indicators): suggestions.insert(1, "Increase lexical diversity and avoid repetitive or predictable phrasing.") if any("Uniform sentence rhythm" in ind for ind in indicators): suggestions.insert(2, "Introduce more irregular sentence flow with natural pauses and variation.") if any("Binoculars zero-shot" in ind for ind in indicators): suggestions.append("Shift away from statistical-sounding phrasing toward concrete, humanized language.") elif verdict == "UNCERTAIN": suggestions = [ "If you want a more human voice, add unique details, varied tone, and irregular sentence cadence.", "If you want a polished AI-style tone, make the language more consistent and formal.", "Use vivid examples and conversational transitions to reduce ambiguity.", "Balance structure with occasional human-style breaks such as rhetorical questions or shorter sentences." ] else: suggestions = [ "Preserve your natural voice and sentence variety; this supports a human writing profile.", "Use concrete examples, specific context, and varied punctuation for authentic human style.", "Keep the dynamic rhythm and lexical richness that make the text feel organic.", "Avoid overly formal or repetitive phrases unless you want a polished editorial tone." ] if any("High linguistic entropy" in ind for ind in indicators): suggestions.insert(1, "Keep the rich vocabulary and creative phrasing that signal human authorship.") if any("Dynamic rhythmic variance" in ind for ind in indicators): suggestions.append("Preserve the irregular sentence cadence that gives this text a natural flow.") if word_count < 150: suggestions.append("Use more than 150 words for a more reliable forensic assessment.") return suggestions def _generate_ai_suggestions(text: str, verdict: str, indicators: List[str]) -> List[str]: if not settings.GEMINI_API_KEY or len(text.strip()) < 80: return [] try: import google.generativeai as genai genai.configure(api_key=settings.GEMINI_API_KEY) model_name = settings.GEMINI_MODEL or "gemini-2.0-flash" model = genai.GenerativeModel(model_name) prompt = ( "You are a practical writing assistant. Based on the following text verdict and indicators, " "provide 4 short improvement suggestions. Return only a JSON array of strings.\n\n" f"Verdict: {verdict}\n" f"Indicators: {', '.join(indicators) or 'none'}\n" "Text sample: """" + text[:1200] + """"\n" "JSON:" ) response = model.generate_content( prompt, generation_config={"max_output_tokens": 180, "temperature": 0.7} ) raw = response.text.strip() raw = raw.replace('```json', '').replace('```', '').strip() import json suggestions = json.loads(raw) if isinstance(suggestions, list) and all(isinstance(item, str) for item in suggestions): return suggestions except Exception: pass return [] def generate_text_improvement_suggestions(result: Dict[str, Any], text: str = "") -> List[str]: verdict = str(result.get("verdict", "UNCERTAIN")).upper() indicators = result.get("indicators") or [] if not isinstance(indicators, list): indicators = [str(indicators)] word_count = result.get("word_count") or len(text.split()) suggestions = _build_rule_suggestions(verdict, [str(i) for i in indicators], word_count) ai_suggestions = _generate_ai_suggestions(text, verdict, [str(i) for i in indicators]) if ai_suggestions: return ai_suggestions return suggestions