conversantech commited on
Commit
4facc83
Β·
1 Parent(s): 2c89e89
Files changed (1) hide show
  1. app.py +238 -84
app.py CHANGED
@@ -5,6 +5,7 @@ import re
5
  import nltk
6
  from nltk.tokenize import sent_tokenize, word_tokenize
7
  from textstat import flesch_reading_ease, flesch_kincaid_grade
 
8
 
9
  # Setup NLTK download path for Hugging Face Spaces
10
  os.environ['NLTK_DATA'] = '/tmp/nltk_data'
@@ -36,26 +37,38 @@ class AIContentHumanizer:
36
  self.setup_humanization_patterns()
37
 
38
  def setup_humanization_patterns(self):
39
- """Setup patterns for AI phrase replacement"""
40
- self.ai_replacements = {
41
- r'\bit is important to note that\b': ["worth mentioning that", "keep in mind that", "note that"],
42
- r'\bit is worth noting that\b': ["interestingly", "notably", "it's worth mentioning"],
43
- r'\bin conclusion\b': ["to wrap up", "all in all", "bottom line"],
44
- r'\bfurthermore\b': ["plus", "also", "on top of that"],
45
- r'\bmoreover\b': ["what's more", "besides", "additionally"],
46
- r'\bhowever\b': ["but", "though", "on the flip side"],
47
- r'\bnevertheless\b': ["still", "even so", "that said"],
48
- r'\btherefore\b': ["so", "thus", "as a result"],
49
- r'\bconsequently\b': ["as a result", "so", "because of this"],
50
- r'\bin order to\b': ["to", "so we can", "for"],
51
- r'\bdue to the fact that\b': ["because", "since", "given that"],
52
- r'\bwith regard to\b': ["about", "regarding", "when it comes to"],
53
- r'\bit should be noted that\b': ["note that", "remember", "keep in mind"],
54
- r'\bit is essential to\b': ["you need to", "it's crucial to", "make sure to"],
55
- r'\bsubsequently\b': ["then", "next", "after that"],
56
- r'\bultimately\b': ["in the end", "finally", "when all is said and done"]
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
 
 
59
  self.contractions = {
60
  r'\bdo not\b': "don't",
61
  r'\bdoes not\b': "doesn't",
@@ -83,95 +96,206 @@ class AIContentHumanizer:
83
  r'\bI have\b': "I've",
84
  r'\byou have\b': "you've",
85
  r'\bwe have\b': "we've",
86
- r'\bthey have\b': "they've"
 
 
 
 
 
87
  }
88
 
89
- self.casual_fillers = [
 
 
 
 
 
 
 
 
90
  "you know", "I mean", "like", "actually", "basically",
91
- "honestly", "literally", "obviously", "clearly", "definitely"
 
 
 
92
  ]
93
 
94
- self.personal_touches = [
95
- "I think", "in my opinion", "from what I've seen", "personally",
96
- "if you ask me", "the way I see it", "from my experience"
 
 
 
97
  ]
98
 
99
  def replace_ai_phrases(self, text):
100
- """Replace formal AI phrases with more casual alternatives"""
101
- for pattern, replacements in self.ai_replacements.items():
102
- if re.search(pattern, text, re.IGNORECASE):
103
  replacement = random.choice(replacements)
104
- text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
105
  return text
106
 
107
  def add_contractions(self, text):
108
- """Add contractions to make text more casual"""
109
  for pattern, contraction in self.contractions.items():
110
  text = re.sub(pattern, contraction, text, flags=re.IGNORECASE)
111
  return text
112
 
113
- def vary_sentence_structure(self, text):
114
- """Add variety to sentence structure"""
115
- try:
116
- sentences = sent_tokenize(text)
117
- varied_sentences = []
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- for sentence in sentences:
120
- # Randomly add sentence starters
121
- if random.random() < 0.3 and len(sentence.split()) > 8:
122
- starters = ["Well,", "So,", "Now,", "Look,", "Here's the thing -"]
123
- sentence = f"{random.choice(starters)} {sentence.lower()}"
124
-
125
- varied_sentences.append(sentence)
126
 
127
- return " ".join(varied_sentences)
128
- except Exception:
129
- return text
130
 
131
- def add_personal_touches(self, text):
132
- """Add personal opinions and touches"""
133
  sentences = sent_tokenize(text)
134
- if len(sentences) > 2 and random.random() < 0.4:
135
- insert_pos = random.randint(1, len(sentences) - 1)
136
- personal_touch = random.choice(self.personal_touches)
137
- sentences[insert_pos] = f"{personal_touch}, {sentences[insert_pos].lower()}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  return " ".join(sentences)
140
 
141
- def add_casual_punctuation(self, text):
142
- """Add casual punctuation like dashes and ellipses"""
143
- # Replace some periods with dashes for emphasis
144
- text = re.sub(r'(\w+)\. ([A-Z])', r'\1 - \2', text)
145
 
146
- # Add occasional ellipses
147
- if random.random() < 0.3:
148
- text = re.sub(r'(\w+)\.', r'\1...', text, count=1)
149
 
150
- return text
 
 
 
 
 
 
 
 
151
 
152
- def add_natural_fillers(self, text):
153
- """Add natural conversation fillers"""
154
  sentences = sent_tokenize(text)
155
- if len(sentences) > 1 and random.random() < 0.5:
156
- filler_pos = random.randint(0, len(sentences) - 1)
157
- filler = random.choice(self.casual_fillers)
158
- sentences[filler_pos] = f"{filler}, {sentences[filler_pos].lower()}"
 
 
 
 
 
 
159
 
160
  return " ".join(sentences)
161
 
162
- def clean_text(self, text):
163
- """Clean up the text formatting"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  # Fix spacing issues
165
  text = re.sub(r'\s+', ' ', text)
166
  text = re.sub(r'\s+([,.!?])', r'\1', text)
167
 
168
- # Fix capitalization after sentence starters
169
  text = re.sub(r'([.!?]\s+)([a-z])', lambda m: m.group(1) + m.group(2).upper(), text)
 
170
 
171
  # Ensure first letter is capitalized
172
  if text and text[0].islower():
173
  text = text[0].upper() + text[1:]
174
 
 
 
 
175
  return text.strip()
176
 
177
  def get_readability_score(self, text):
@@ -187,8 +311,8 @@ class AIContentHumanizer:
187
  except Exception as e:
188
  return f"Could not calculate readability: {str(e)}"
189
 
190
- def humanize_text(self, text, intensity="medium"):
191
- """Main method to humanize AI-generated text"""
192
  if not text or not text.strip():
193
  return "Please provide text to humanize."
194
 
@@ -203,19 +327,24 @@ class AIContentHumanizer:
203
  except Exception as nltk_error:
204
  return f"NLTK Error: {str(nltk_error)}. Please try again or contact support."
205
 
206
- # Apply humanization techniques based on intensity
207
  text = self.replace_ai_phrases(text)
208
  text = self.add_contractions(text)
 
209
 
210
  if intensity in ["medium", "heavy"]:
211
- text = self.vary_sentence_structure(text)
212
- text = self.add_personal_touches(text)
213
- text = self.add_casual_punctuation(text)
 
214
 
215
  if intensity == "heavy":
216
- text = self.add_natural_fillers(text)
 
 
 
217
 
218
- return self.clean_text(text)
219
 
220
  except Exception as e:
221
  return f"Error processing text: {str(e)}\n\nOriginal text: {text}"
@@ -234,22 +363,47 @@ def create_interface():
234
  except Exception as e:
235
  return f"Error: {str(e)}", "Processing error"
236
 
237
- with gr.Blocks(title="AI Content Humanizer") as interface:
238
- gr.Markdown("""# πŸ€–βž‘οΈπŸ‘€ AI Content Humanizer
239
- Transform AI-generated content into human-sounding, casual, and readable text!""")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
- input_text = gr.Textbox(label="AI-generated Text", lines=8, placeholder="Paste your AI-generated text here...")
242
- intensity = gr.Radio(["light", "medium", "heavy"], value="medium", label="Humanization Level")
243
- output_text = gr.Textbox(label="Humanized Text", lines=8, show_copy_button=True)
244
- readability = gr.Textbox(label="Readability Score", lines=2)
 
 
 
245
 
246
- btn = gr.Button("Humanize Text", variant="primary")
247
  btn.click(fn=process_text, inputs=[input_text, intensity], outputs=[output_text, readability])
248
  input_text.submit(fn=process_text, inputs=[input_text, intensity], outputs=[output_text, readability])
249
 
250
  return interface
251
 
252
  if __name__ == "__main__":
253
- print("Starting AI Content Humanizer...")
254
  app = create_interface()
255
  app.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
 
5
  import nltk
6
  from nltk.tokenize import sent_tokenize, word_tokenize
7
  from textstat import flesch_reading_ease, flesch_kincaid_grade
8
+ import string
9
 
10
  # Setup NLTK download path for Hugging Face Spaces
11
  os.environ['NLTK_DATA'] = '/tmp/nltk_data'
 
37
  self.setup_humanization_patterns()
38
 
39
  def setup_humanization_patterns(self):
40
+ """Setup comprehensive patterns for maximum humanization"""
41
+ # Avoid AI-flagged terms completely
42
+ self.ai_flagged_terms = {
43
+ r'\brealm\b': ["world", "area", "field", "space", "domain"],
44
+ r'\bdelve\b': ["explore", "dig into", "look at", "examine", "dive into"],
45
+ r'\bembark\b': ["start", "begin", "kick off", "launch into"],
46
+ r'\ba testament to\b': ["shows", "proves", "demonstrates", "reflects"],
47
+ r'\bthe landscape of\b': ["the world of", "the field of", "the area of"],
48
+ r'\bnavigating\b': ["dealing with", "handling", "managing", "working through"],
49
+ r'\bmeticulous\b': ["careful", "detailed", "thorough", "precise"],
50
+ r'\bintricate\b': ["complex", "detailed", "complicated", "elaborate"],
51
+ r'\bfurthermore\b': ["plus", "also", "and", "what's more"],
52
+ r'\bmoreover\b': ["also", "plus", "and", "on top of that"],
53
+ r'\bhowever\b': ["but", "though", "yet", "still"],
54
+ r'\bnevertheless\b': ["but", "still", "even so", "anyway"],
55
+ r'\btherefore\b': ["so", "thus", "that's why", "because of this"],
56
+ r'\bconsequently\b': ["so", "as a result", "because of this"],
57
+ r'\bin conclusion\b': ["to wrap up", "bottom line", "all in all"],
58
+ r'\bit is important to note\b': ["worth mentioning", "keep in mind", "note that"],
59
+ r'\bit should be noted\b': ["remember", "keep in mind", "note that"],
60
+ r'\bsignificant\b': ["big", "major", "important", "huge"],
61
+ r'\bsubstantial\b': ["big", "large", "major", "significant"],
62
+ r'\bcomprehensive\b': ["complete", "full", "thorough", "detailed"],
63
+ r'\boptimal\b': ["best", "ideal", "perfect", "top"],
64
+ r'\bfacilitate\b': ["help", "make easier", "enable", "assist"],
65
+ r'\butilize\b': ["use", "employ", "apply", "work with"],
66
+ r'\bleverage\b': ["use", "take advantage of", "make use of"],
67
+ r'\benhance\b': ["improve", "boost", "make better", "upgrade"],
68
+ r'\bimplement\b': ["put in place", "set up", "start using", "apply"]
69
  }
70
 
71
+ # More natural contractions
72
  self.contractions = {
73
  r'\bdo not\b': "don't",
74
  r'\bdoes not\b': "doesn't",
 
96
  r'\bI have\b': "I've",
97
  r'\byou have\b': "you've",
98
  r'\bwe have\b': "we've",
99
+ r'\bthey have\b': "they've",
100
+ r'\bthat is\b': "that's",
101
+ r'\bit is\b': "it's",
102
+ r'\bwho is\b': "who's",
103
+ r'\bwhat is\b': "what's",
104
+ r'\bwhere is\b': "where's"
105
  }
106
 
107
+ # Casual conversation starters
108
+ self.conversation_starters = [
109
+ "Look,", "Listen,", "Here's the thing -", "You know what?",
110
+ "Honestly,", "Real talk -", "Let me tell you,", "So here's what I think -",
111
+ "Okay, so", "Right, so", "Well,", "Actually,", "Basically,"
112
+ ]
113
+
114
+ # Natural fillers and expressions
115
+ self.natural_expressions = [
116
  "you know", "I mean", "like", "actually", "basically",
117
+ "honestly", "literally", "obviously", "clearly", "definitely",
118
+ "pretty much", "kind of", "sort of", "more or less", "at the end of the day",
119
+ "when it comes down to it", "if you ask me", "in my experience",
120
+ "from what I've seen", "the way I see it"
121
  ]
122
 
123
+ # Personal perspective phrases
124
+ self.personal_phrases = [
125
+ "I think", "in my opinion", "from my experience", "personally",
126
+ "if you ask me", "the way I see it", "from what I've seen",
127
+ "in my view", "as I see it", "my take is", "I believe",
128
+ "it seems to me", "I'd say", "my guess is"
129
  ]
130
 
131
  def replace_ai_phrases(self, text):
132
+ """Aggressively replace AI-flagged terms"""
133
+ for pattern, replacements in self.ai_flagged_terms.items():
134
+ while re.search(pattern, text, re.IGNORECASE):
135
  replacement = random.choice(replacements)
136
+ text = re.sub(pattern, replacement, text, flags=re.IGNORECASE, count=1)
137
  return text
138
 
139
  def add_contractions(self, text):
140
+ """Add extensive contractions"""
141
  for pattern, contraction in self.contractions.items():
142
  text = re.sub(pattern, contraction, text, flags=re.IGNORECASE)
143
  return text
144
 
145
+ def add_human_imperfections(self, text):
146
+ """Add subtle human-like imperfections"""
147
+ sentences = sent_tokenize(text)
148
+ modified_sentences = []
149
+
150
+ for sentence in sentences:
151
+ # Add occasional typos that are quickly corrected
152
+ if random.random() < 0.1:
153
+ words = sentence.split()
154
+ if len(words) > 5:
155
+ # Add a self-correction
156
+ correction_phrases = ["I mean", "or rather", "well, actually", "sorry,"]
157
+ correction = random.choice(correction_phrases)
158
+ insert_pos = random.randint(2, len(words) - 2)
159
+ words.insert(insert_pos, f"- {correction} -")
160
+ sentence = " ".join(words)
161
 
162
+ # Add hesitation markers
163
+ if random.random() < 0.15:
164
+ hesitations = ["um,", "uh,", "well,", "so,", "like,"]
165
+ hesitation = random.choice(hesitations)
166
+ sentence = f"{hesitation} {sentence.lower()}"
167
+ sentence = sentence[0].upper() + sentence[1:]
 
168
 
169
+ modified_sentences.append(sentence)
170
+
171
+ return " ".join(modified_sentences)
172
 
173
+ def vary_sentence_structure_advanced(self, text):
174
+ """Advanced sentence structure variation"""
175
  sentences = sent_tokenize(text)
176
+ varied_sentences = []
177
+
178
+ for i, sentence in enumerate(sentences):
179
+ words = sentence.split()
180
+
181
+ # Add conversation starters randomly
182
+ if random.random() < 0.25 and len(words) > 6:
183
+ starter = random.choice(self.conversation_starters)
184
+ sentence = f"{starter} {sentence.lower()}"
185
+ sentence = sentence[0].upper() + sentence[1:]
186
+
187
+ # Break long sentences with interjections
188
+ if len(words) > 15 and random.random() < 0.4:
189
+ mid_point = len(words) // 2
190
+ interjection = random.choice(["- and this is key -", "- here's the thing -", "- get this -"])
191
+ words.insert(mid_point, interjection)
192
+ sentence = " ".join(words)
193
+
194
+ # Add questions to engage reader
195
+ if random.random() < 0.2 and i > 0:
196
+ questions = ["Right?", "You know?", "Make sense?", "See what I mean?"]
197
+ sentence += f" {random.choice(questions)}"
198
+
199
+ varied_sentences.append(sentence)
200
+
201
+ return " ".join(varied_sentences)
202
+
203
+ def add_personal_touches_advanced(self, text):
204
+ """Add extensive personal touches"""
205
+ sentences = sent_tokenize(text)
206
+
207
+ # Add personal anecdotes
208
+ if len(sentences) > 3 and random.random() < 0.3:
209
+ anecdotes = [
210
+ "I've been there myself, and",
211
+ "From my own experience,",
212
+ "I remember when I first learned this -",
213
+ "This reminds me of something that happened to me -"
214
+ ]
215
+ insert_pos = random.randint(1, len(sentences) - 2)
216
+ anecdote = random.choice(anecdotes)
217
+ sentences[insert_pos] = f"{anecdote} {sentences[insert_pos].lower()}"
218
+
219
+ # Add personal opinions
220
+ for i in range(len(sentences)):
221
+ if random.random() < 0.3:
222
+ personal_phrase = random.choice(self.personal_phrases)
223
+ sentences[i] = f"{personal_phrase}, {sentences[i].lower()}"
224
+ sentences[i] = sentences[i][0].upper() + sentences[i][1:]
225
 
226
  return " ".join(sentences)
227
 
228
+ def add_casual_punctuation_advanced(self, text):
229
+ """Advanced casual punctuation"""
230
+ # Add em dashes for emphasis
231
+ text = re.sub(r'(\w+)\. ([A-Z])', r'\1 β€” \2', text)
232
 
233
+ # Add ellipses for pauses
234
+ if random.random() < 0.4:
235
+ text = re.sub(r'(\w+)\.', r'\1...', text, count=random.randint(1, 2))
236
 
237
+ # Add parenthetical asides
238
+ sentences = sent_tokenize(text)
239
+ if len(sentences) > 2 and random.random() < 0.3:
240
+ asides = ["(trust me on this)", "(I know, I know)", "(bear with me)", "(you'll see why)"]
241
+ insert_pos = random.randint(1, len(sentences) - 1)
242
+ aside = random.choice(asides)
243
+ sentences[insert_pos] += f" {aside}"
244
+
245
+ return " ".join(sentences)
246
 
247
+ def add_natural_fillers_advanced(self, text):
248
+ """Add extensive natural conversation fillers"""
249
  sentences = sent_tokenize(text)
250
+
251
+ for i in range(len(sentences)):
252
+ if random.random() < 0.4:
253
+ filler = random.choice(self.natural_expressions)
254
+ # Insert filler at different positions
255
+ words = sentences[i].split()
256
+ if len(words) > 4:
257
+ insert_pos = random.randint(1, min(3, len(words) - 1))
258
+ words.insert(insert_pos, f"{filler},")
259
+ sentences[i] = " ".join(words)
260
 
261
  return " ".join(sentences)
262
 
263
+ def add_colloquialisms(self, text):
264
+ """Add colloquial expressions and slang"""
265
+ colloquial_replacements = {
266
+ r'\bvery good\b': ["pretty great", "really solid", "super good"],
267
+ r'\bvery bad\b': ["pretty awful", "really rough", "super bad"],
268
+ r'\bvery important\b': ["super important", "really key", "pretty crucial"],
269
+ r'\ba lot of\b': ["tons of", "loads of", "plenty of", "heaps of"],
270
+ r'\bmany people\b': ["lots of folks", "tons of people", "loads of people"],
271
+ r'\bquickly\b': ["fast", "in a flash", "super quick"],
272
+ r'\bslowly\b': ["at a snail's pace", "pretty slow", "taking forever"]
273
+ }
274
+
275
+ for pattern, replacements in colloquial_replacements.items():
276
+ if re.search(pattern, text, re.IGNORECASE):
277
+ replacement = random.choice(replacements)
278
+ text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
279
+
280
+ return text
281
+
282
+ def clean_text_advanced(self, text):
283
+ """Advanced text cleaning with natural formatting"""
284
  # Fix spacing issues
285
  text = re.sub(r'\s+', ' ', text)
286
  text = re.sub(r'\s+([,.!?])', r'\1', text)
287
 
288
+ # Fix capitalization after sentence starters and interjections
289
  text = re.sub(r'([.!?]\s+)([a-z])', lambda m: m.group(1) + m.group(2).upper(), text)
290
+ text = re.sub(r'(^|\. )([a-z])', lambda m: m.group(1) + m.group(2).upper(), text)
291
 
292
  # Ensure first letter is capitalized
293
  if text and text[0].islower():
294
  text = text[0].upper() + text[1:]
295
 
296
+ # Clean up multiple punctuation
297
+ text = re.sub(r'([.!?]){2,}', r'\1', text)
298
+
299
  return text.strip()
300
 
301
  def get_readability_score(self, text):
 
311
  except Exception as e:
312
  return f"Could not calculate readability: {str(e)}"
313
 
314
+ def humanize_text(self, text, intensity="heavy"):
315
+ """Main method to humanize AI-generated text with maximum effectiveness"""
316
  if not text or not text.strip():
317
  return "Please provide text to humanize."
318
 
 
327
  except Exception as nltk_error:
328
  return f"NLTK Error: {str(nltk_error)}. Please try again or contact support."
329
 
330
+ # Apply aggressive humanization for 0% AI detection
331
  text = self.replace_ai_phrases(text)
332
  text = self.add_contractions(text)
333
+ text = self.add_colloquialisms(text)
334
 
335
  if intensity in ["medium", "heavy"]:
336
+ text = self.vary_sentence_structure_advanced(text)
337
+ text = self.add_personal_touches_advanced(text)
338
+ text = self.add_casual_punctuation_advanced(text)
339
+ text = self.add_natural_fillers_advanced(text)
340
 
341
  if intensity == "heavy":
342
+ text = self.add_human_imperfections(text)
343
+ # Apply multiple passes for maximum humanization
344
+ text = self.replace_ai_phrases(text) # Second pass
345
+ text = self.add_natural_fillers_advanced(text) # Second pass
346
 
347
+ return self.clean_text_advanced(text)
348
 
349
  except Exception as e:
350
  return f"Error processing text: {str(e)}\n\nOriginal text: {text}"
 
363
  except Exception as e:
364
  return f"Error: {str(e)}", "Processing error"
365
 
366
+ with gr.Blocks(title="AI Content Humanizer - 0% Detection", theme=gr.themes.Soft()) as interface:
367
+ gr.Markdown("""# πŸ€–βž‘οΈπŸ‘€ Advanced AI Content Humanizer
368
+ **Achieve 0% AI Detection Score** - Transform AI content into completely human-sounding text!""")
369
+
370
+ with gr.Row():
371
+ with gr.Column():
372
+ input_text = gr.Textbox(
373
+ label="AI-generated Text",
374
+ lines=10,
375
+ placeholder="Paste your AI-generated text here for maximum humanization..."
376
+ )
377
+ intensity = gr.Radio(
378
+ ["light", "medium", "heavy"],
379
+ value="heavy",
380
+ label="Humanization Level",
381
+ info="Heavy mode recommended for 0% AI detection"
382
+ )
383
+ btn = gr.Button("πŸš€ Humanize for 0% AI Detection", variant="primary", size="lg")
384
+
385
+ with gr.Column():
386
+ output_text = gr.Textbox(
387
+ label="Humanized Text (0% AI Detection)",
388
+ lines=10,
389
+ show_copy_button=True
390
+ )
391
+ readability = gr.Textbox(label="Readability Score", lines=3)
392
 
393
+ gr.Markdown("""
394
+ ### πŸ’‘ Tips for 0% AI Detection:
395
+ - Use **Heavy** mode for maximum humanization
396
+ - The tool adds natural conversation patterns, personal touches, and human imperfections
397
+ - Removes all AI-flagged terms and phrases
398
+ - Test your output with multiple AI detectors for verification
399
+ """)
400
 
 
401
  btn.click(fn=process_text, inputs=[input_text, intensity], outputs=[output_text, readability])
402
  input_text.submit(fn=process_text, inputs=[input_text, intensity], outputs=[output_text, readability])
403
 
404
  return interface
405
 
406
  if __name__ == "__main__":
407
+ print("Starting Advanced AI Content Humanizer for 0% Detection...")
408
  app = create_interface()
409
  app.launch(server_name="0.0.0.0", server_port=7860, show_error=True)