Humaira81 commited on
Commit
003d301
·
verified ·
1 Parent(s): 52c9494

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +164 -22
app.py CHANGED
@@ -1,39 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
- import random
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- # Dummy logic (replace with your model later)
5
- def humanize_and_detect(text):
6
- # Simulated refined output
7
- refined = f"This is the humanized version of your text:\n\n{text}"
 
 
 
 
 
8
 
9
- # Simulated AI-likeness score
10
- score = random.uniform(0.3, 0.95)
11
- ai_score = f"AI-likeness score: {score:.2f} ({'Likely Human' if score < 0.5 else 'Likely AI'})"
 
 
 
 
 
 
 
 
 
12
 
13
- return refined, ai_score
 
 
 
 
14
 
15
- # Minimal Gradio interface
16
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  gr.Markdown(
18
  """
19
- # 🕌 Zawiyah AI Collective Humanizer AI
 
20
  Refine your writing & detect AI-likeness. Simple, clean, effective.
21
-
22
- ---
23
  """
24
  )
25
 
26
- input_text = gr.Textbox(label="✍️ Paste Your Text Here", placeholder="Enter text...", lines=6)
27
-
28
- submit_btn = gr.Button("🚀 Refine & Detect")
29
 
30
- output_refined = gr.Textbox(label="🧠 Humanized Output", lines=6)
31
- ai_score = gr.Textbox(label="🤖 AI Detection Result")
 
 
 
32
 
33
- submit_btn.click(fn=humanize_and_detect,
34
  inputs=input_text,
35
  outputs=[output_refined, ai_score])
36
 
37
- demo.queue().launch()
38
-
39
 
 
 
 
 
1
+ # Zawiyah AI Collective — Humanizer AI (Style 4 + Detector)
2
+ # ----------------------------------------------------------
3
+ # Requirements:
4
+ # pip install gradio openai
5
+ # Environment:
6
+ # export OPENAI_API_KEY="sk-..."
7
+ # Optional:
8
+ # export OPENAI_BASE_URL="https://api.openai.com/v1" # if using default, you can skip
9
+
10
+ import os
11
+ import json
12
  import gradio as gr
13
+ from openai import OpenAI
14
+
15
+ # --- CONFIG ---
16
+ MODEL_HUMANIZER = "gpt-5" # use your strongest model name here
17
+ MODEL_DETECTOR = "gpt-5" # same model is fine for classification
18
+ TEMPERATURE_REWRITE = 0.6 # a bit of variation, still controlled
19
+ MAX_TOKENS_REWRITE = 1200 # adjust per your quotas
20
+
21
+ # --- CLIENT ---
22
+ def get_client():
23
+ # Allows custom base (useful for proxies / gateways), otherwise defaults to api.openai.com
24
+ base_url = os.environ.get("OPENAI_BASE_URL", None)
25
+ if base_url:
26
+ return OpenAI(api_key=os.environ.get("OPENAI_API_KEY"), base_url=base_url)
27
+ return OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
28
+
29
+ # --- PROMPTS ---
30
+ SYSTEM_HUMANIZER = (
31
+ "You are Zawiyah AI Humanizer. Rewrite text into neutral, balanced human English.\n"
32
+ "Goals: preserve meaning; improve clarity; vary sentence length; prefer concrete verbs; reduce filler.\n"
33
+ "Keep citations/URLs; maintain lists; remove obvious LLM tells (e.g., 'as an AI', 'in conclusion' unless necessary).\n"
34
+ "Avoid plagiarism; do not invent facts; keep numbers and named entities unchanged unless the user text is ambiguous.\n"
35
+ "Tone: natural, calm, and human—no corporate buzzwords, no robotic cadence. Keep it concise but not terse."
36
+ )
37
 
38
+ USER_HUMANIZER_TEMPLATE = (
39
+ "Rewrite the text below into natural, balanced human English suited for a wide audience.\n"
40
+ "Constraints:\n"
41
+ "- Preserve all factual content, names, figures, and citations.\n"
42
+ "- Remove repetitive phrasing and overly formal constructions.\n"
43
+ "- Prefer contractions where natural (I'm, we'll) and mix short & long sentences.\n"
44
+ "- Keep formatting if present (bullet lists, headings) but tidy it up.\n\n"
45
+ "Text:\n```text\n{src}\n```"
46
+ )
47
 
48
+ SYSTEM_DETECTOR = (
49
+ "You are an AI-likeness detector. Given ORIGINAL and REWRITTEN text, estimate the likelihood the text "
50
+ "was produced by an AI writing model. Return a **strict JSON** object with keys:\n"
51
+ '{\n'
52
+ ' "ai_likeness_score": float in [0,1], // higher = more likely AI\n'
53
+ ' "verdict": "Likely Human" | "Unclear" | "Likely AI",\n'
54
+ ' "rationale": string (1-2 concise reasons),\n'
55
+ ' "signals": [ up to 5 short phrases e.g., "uniform sentence length", "hedging", "template phrases" ]\n'
56
+ '}\n'
57
+ "Focus on stylistic signals (cadence, repetition, template markers), not topic.\n"
58
+ "Be conservative—when uncertain, push score toward 0.5 and verdict 'Unclear'."
59
+ )
60
 
61
+ USER_DETECTOR_TEMPLATE = (
62
+ "ORIGINAL:\n```text\n{orig}\n```\n\n"
63
+ "REWRITTEN:\n```text\n{rew}\n```\n\n"
64
+ "Return only the JSON. No prose."
65
+ )
66
 
67
+ # --- CORE FUNCTIONS ---
68
+ def run_humanizer(text: str) -> str:
69
+ """Rewrite into neutral, balanced human English."""
70
+ if not text or not text.strip():
71
+ return "Please paste some text above."
72
+ client = get_client()
73
+ resp = client.chat.completions.create(
74
+ model=MODEL_HUMANIZER,
75
+ temperature=TEMPERATURE_REWRITE,
76
+ max_tokens=MAX_TOKENS_REWRITE,
77
+ messages=[
78
+ {"role": "system", "content": SYSTEM_HUMANIZER},
79
+ {"role": "user", "content": USER_HUMANIZER_TEMPLATE.format(src=text)}
80
+ ]
81
+ )
82
+ return resp.choices[0].message.content.strip()
83
+
84
+ def run_detector(original_text: str, rewritten_text: str) -> dict:
85
+ """Return dict: {ai_likeness_score, verdict, rationale, signals}"""
86
+ if not rewritten_text.strip():
87
+ return {
88
+ "ai_likeness_score": 0.5,
89
+ "verdict": "Unclear",
90
+ "rationale": "No rewritten content provided.",
91
+ "signals": []
92
+ }
93
+ client = get_client()
94
+ resp = client.chat.completions.create(
95
+ model=MODEL_DETECTOR,
96
+ temperature=0.0,
97
+ max_tokens=400,
98
+ messages=[
99
+ {"role": "system", "content": SYSTEM_DETECTOR},
100
+ {"role": "user", "content": USER_DETECTOR_TEMPLATE.format(orig=original_text, rew=rewritten_text)}
101
+ ]
102
+ )
103
+ raw = resp.choices[0].message.content.strip()
104
+ # Safe JSON parsing
105
+ try:
106
+ data = json.loads(raw)
107
+ # Minimal validation
108
+ score = float(data.get("ai_likeness_score", 0.5))
109
+ verdict = str(data.get("verdict", "Unclear"))
110
+ rationale = str(data.get("rationale", ""))
111
+ signals = data.get("signals", [])
112
+ if not isinstance(signals, list):
113
+ signals = []
114
+ return {
115
+ "ai_likeness_score": max(0.0, min(1.0, score)),
116
+ "verdict": verdict,
117
+ "rationale": rationale,
118
+ "signals": signals[:5]
119
+ }
120
+ except Exception:
121
+ # Fallback: return raw content in rationale for debugging
122
+ return {
123
+ "ai_likeness_score": 0.5,
124
+ "verdict": "Unclear",
125
+ "rationale": f"Non-JSON response from model: {raw[:300]}",
126
+ "signals": []
127
+ }
128
+
129
+ def humanize_and_detect_pipeline(text: str):
130
+ try:
131
+ rewritten = run_humanizer(text)
132
+ det = run_detector(text, rewritten)
133
+ # Pretty print detector for the right-hand panel
134
+ verdict_line = f"{det['verdict']} (score: {det['ai_likeness_score']:.2f})"
135
+ details = "• " + "; ".join(det["signals"]) if det["signals"] else ""
136
+ detector_out = f"{verdict_line}\n{det['rationale']}\n{details}"
137
+ return rewritten, detector_out
138
+ except Exception as e:
139
+ return (
140
+ "⚠️ Error during processing. Please check your API key / quota.",
141
+ f"Error: {type(e).__name__}: {str(e)}"
142
+ )
143
+
144
+ # --- UI ---
145
+ custom_css = """
146
+ #title {text-align:center; font-size:32px; font-weight:800;}
147
+ .gradio-container {max-width:880px !important; margin:auto;}
148
+ .section-box {border:1px solid #e6e6e6; padding:18px; border-radius:16px; background:#fafafa;}
149
+ #footer {text-align:center; font-size:12px; color:#666; margin-top:12px;}
150
+ """
151
+
152
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
153
  gr.Markdown(
154
  """
155
+ <div id="title">🕌 Zawiyah AI Collective <span style='color:#8E0000'>Humanizer AI</span></div>
156
+ <p style="text-align:center; font-size:16px; margin-top:-8px">
157
  Refine your writing & detect AI-likeness. Simple, clean, effective.
158
+ </p>
159
+ <hr>
160
  """
161
  )
162
 
163
+ with gr.Column(elem_classes="section-box"):
164
+ input_text = gr.Textbox(label="✍️ Paste Your Text Here", placeholder="Enter text…", lines=10)
165
+ submit_btn = gr.Button("🚀 Refine & Detect", size="lg")
166
 
167
+ with gr.Row():
168
+ with gr.Column(elem_classes="section-box"):
169
+ output_refined = gr.Textbox(label="🧠 Humanized Output", lines=12)
170
+ with gr.Column(elem_classes="section-box"):
171
+ ai_score = gr.Textbox(label="🤖 AI Detection Result", lines=12)
172
 
173
+ submit_btn.click(fn=humanize_and_detect_pipeline,
174
  inputs=input_text,
175
  outputs=[output_refined, ai_score])
176
 
177
+ gr.Markdown("<div id='footer'>Zawiyah AI Collective · Malaysia · v1.0 BETA · Built with Gradio</div>")
 
178
 
179
+ if __name__ == "__main__":
180
+ # On Hugging Face Spaces, don't set share=True. Local dev: share=True if you want a public URL.
181
+ demo.queue().launch()