Spaces:
Sleeping
Sleeping
| 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 | |