eheguy commited on
Commit
ae53040
Β·
1 Parent(s): 595bc44

Add readability and purpose controls to humanizer

Browse files
Files changed (2) hide show
  1. humanizer.py +65 -20
  2. main.py +16 -2
humanizer.py CHANGED
@@ -1,33 +1,63 @@
1
  import os
2
  from groq import Groq
3
 
 
4
  SIMPLE_PROMPT = """You are a light text editor. Rewrite the text the user sends with these rules only:
5
- 1. Remove any of these phrases entirely: "It is important to note", "In today's fast-paced world", "Furthermore", "Moreover", "In conclusion", "When it comes to", "It is worth noting", "Needless to say", "In the realm of", "It goes without saying".
6
- 2. Replace obvious synonym swaps where words feel robotic or overly formal.
 
7
  3. Do NOT change sentence structure, length, or order.
8
  4. Do NOT change the meaning, facts, or argument.
9
  5. Output ONLY the rewritten text. No preamble. No explanation."""
10
 
 
11
  STANDARD_PROMPT = """You are a text restructuring engine. Rewrite the text the user sends with these rules:
 
12
  1. Vary sentence lengths. Mix short sentences (under 8 words) with longer ones (over 25 words). Never have 3 sentences of similar length in a row.
13
- 2. Remove any of these phrases entirely: "It is important to note", "In today's fast-paced world", "Furthermore", "Moreover", "In conclusion", "When it comes to", "It is worth noting", "Needless to say", "In the realm of", "It goes without saying".
14
  3. Flip at least 2 passive voice constructions to active voice.
15
  4. Move a subordinate clause from the end of a sentence to the beginning in at least 2 places.
16
  5. Add 1 or 2 contractions where formal phrasing sits (e.g. "it is" -> "it's").
17
- 6. Do NOT change the meaning, facts, or argument.
18
- 7. Output ONLY the rewritten text. No preamble. No explanation."""
19
-
20
- ENHANCED_PROMPT = """You are an aggressive text humanizer. Rewrite the text the user sends to sound completely natural and human. Follow all of these rules:
21
- 1. Vary sentence lengths dramatically. Short punchy sentences (3-6 words) must appear. Long flowing sentences (30+ words) must appear. No rhythm should feel uniform.
22
- 2. Remove any of these phrases entirely: "It is important to note", "In today's fast-paced world", "Furthermore", "Moreover", "In conclusion", "When it comes to", "It is worth noting", "Needless to say", "In the realm of", "It goes without saying".
23
- 3. Flip all passive voice constructions to active voice.
24
- 4. Move subordinate clauses to unexpected positions.
25
- 5. Add contractions naturally throughout (aim for 30% of sentences).
26
- 6. Add one parenthetical aside somewhere in the text that feels natural.
27
- 7. Replace at least one transition word per paragraph with a casual connector or none at all.
28
- 8. Introduce one slightly informal word choice per paragraph.
29
- 9. Do NOT change the meaning, facts, or argument. All information must be preserved.
30
- 10. Output ONLY the rewritten text. No preamble. No explanation."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  PROMPTS = {
33
  "simple": SIMPLE_PROMPT,
@@ -36,13 +66,28 @@ PROMPTS = {
36
  }
37
 
38
 
39
- async def humanize_text(text: str, mode: str = "standard") -> str:
 
 
 
 
 
40
  api_key = os.getenv("GROQ_API_KEY")
41
  if not api_key:
42
  raise ValueError("GROQ_API_KEY not set in environment variables.")
43
 
44
  client = Groq(api_key=api_key)
45
- system_prompt = PROMPTS.get(mode, STANDARD_PROMPT)
 
 
 
 
 
 
 
 
 
 
46
 
47
  response = client.chat.completions.create(
48
  model="llama-3.1-8b-instant",
@@ -50,7 +95,7 @@ async def humanize_text(text: str, mode: str = "standard") -> str:
50
  {"role": "system", "content": system_prompt},
51
  {"role": "user", "content": text}
52
  ],
53
- temperature=0.7,
54
  max_tokens=2000,
55
  )
56
 
 
1
  import os
2
  from groq import Groq
3
 
4
+ # ── SIMPLE ────────────────────────────────────────────────────────────────────
5
  SIMPLE_PROMPT = """You are a light text editor. Rewrite the text the user sends with these rules only:
6
+
7
+ 1. Remove any of these phrases entirely: "It is important to note", "In today's fast-paced world", "Furthermore", "Moreover", "In conclusion", "When it comes to", "It is worth noting", "Needless to say", "In the realm of", "It goes without saying", "It is crucial to", "One must consider", "It should be noted".
8
+ 2. When choosing words, avoid the most common or obvious choice. Pick the second or third most natural option β€” words a human writer would reach for intuitively.
9
  3. Do NOT change sentence structure, length, or order.
10
  4. Do NOT change the meaning, facts, or argument.
11
  5. Output ONLY the rewritten text. No preamble. No explanation."""
12
 
13
+ # ── STANDARD ──────────────────────────────────────────────────────────────────
14
  STANDARD_PROMPT = """You are a text restructuring engine. Rewrite the text the user sends with these rules:
15
+
16
  1. Vary sentence lengths. Mix short sentences (under 8 words) with longer ones (over 25 words). Never have 3 sentences of similar length in a row.
17
+ 2. Remove any of these phrases entirely: "It is important to note", "In today's fast-paced world", "Furthermore", "Moreover", "In conclusion", "When it comes to", "It is worth noting", "Needless to say", "In the realm of", "It goes without saying", "It is crucial to", "One must consider", "It should be noted".
18
  3. Flip at least 2 passive voice constructions to active voice.
19
  4. Move a subordinate clause from the end of a sentence to the beginning in at least 2 places.
20
  5. Add 1 or 2 contractions where formal phrasing sits (e.g. "it is" -> "it's").
21
+ 6. Word choice entropy: deliberately avoid the most statistically obvious word. Use the second or third most natural synonym instead. Mix formal and casual register β€” one elevated word followed by a plain one. Use collocations and idiomatic phrases a human writer would reach for naturally.
22
+ 7. Do NOT change the meaning, facts, or argument.
23
+ 8. Output ONLY the rewritten text. No preamble. No explanation."""
24
+
25
+ # ── ENHANCED ──────────────────────────────────────────────────────────────────
26
+ ENHANCED_PROMPT = """You are an aggressive text humanizer. Your goal is to make AI-generated text completely undetectable. Follow every rule below without exception:
27
+
28
+ 1. Vary sentence lengths dramatically. Short punchy sentences (3-6 words) must appear at least twice. Long flowing sentences (30+ words) must appear at least twice. No rhythm should feel uniform β€” alternate aggressively.
29
+ 2. Remove any of these phrases entirely: "It is important to note", "In today's fast-paced world", "Furthermore", "Moreover", "In conclusion", "When it comes to", "It is worth noting", "Needless to say", "In the realm of", "It goes without saying", "It is crucial to", "One must consider", "It should be noted".
30
+ 3. Flip ALL passive voice constructions to active voice.
31
+ 4. Move subordinate clauses to unexpected positions β€” beginning, middle, or split across sentences.
32
+ 5. Add contractions naturally throughout (aim for 30-40% of sentences).
33
+ 6. Add one parenthetical aside somewhere in the text that feels completely natural, like a human thinking out loud.
34
+ 7. Replace every transition word (furthermore, however, additionally, consequently) with either a casual connector or no connector at all β€” let sentences carry their own weight.
35
+ 8. Introduce one slightly informal word or phrase per paragraph that breaks the formal pattern.
36
+ 9. Word choice entropy (critical): Never pick the most statistically obvious word. Always reach for the second or third most natural option. Mix registers deliberately β€” pair an elevated word with a plain one in the same sentence. Use idioms, collocations, and expressions that feel instinctive to a human writer but would never be an AI's first choice. Vary word length: short punchy words mixed with longer precise ones.
37
+ 10. Restructure at least one full paragraph β€” change the order sentences appear in while keeping the meaning intact.
38
+ 11. Do NOT change the meaning, facts, or argument. All information must be preserved.
39
+ 12. Output ONLY the rewritten text. No preamble. No explanation. No "Here is the rewritten version"."""
40
+
41
+ # ── READABILITY MODIFIERS ─────────────────────────────────────────────────────
42
+ READABILITY_MODIFIERS = {
43
+ "casual": "Write in a relaxed, conversational tone. Use everyday language, short sentences, and contractions freely. Write like you're talking to a friend.",
44
+ "neutral": "Write in a balanced, natural tone. Neither too formal nor too casual. Aim for clear, readable prose.",
45
+ "formal": "Write in a polished, professional tone. Use precise language and complete sentences. Avoid contractions and slang.",
46
+ "academic": "Write in a scholarly tone appropriate for academic papers. Use discipline-specific vocabulary where natural, complex sentence structures, and avoid contractions entirely.",
47
+ }
48
+
49
+ # ── PURPOSE MODIFIERS ─────────────────────────────────────────────────────────
50
+ PURPOSE_MODIFIERS = {
51
+ "academic": "This is academic writing. Preserve citations, arguments, and scholarly structure. Prioritize clarity and precision.",
52
+ "persuasive": "This is persuasive writing. Keep the argument sharp, the tone confident, and the call to action clear.",
53
+ "professional": "This is professional business writing. Keep it clear, concise, and action-oriented.",
54
+ "personal": "This is personal writing. Make it warm, genuine, and human. First-person voice is appropriate.",
55
+ "essay": "This is an essay. Preserve the thesis, supporting arguments, and conclusion structure.",
56
+ "blog": "This is a blog post. Keep it engaging, punchy, and easy to scan. Use a conversational voice.",
57
+ "email": "This is an email. Keep it concise, direct, and appropriately professional. Use clear subject-verb-object sentences.",
58
+ "social media": "This is social media content. Keep it short, punchy, and engaging. Use natural language and energy.",
59
+ "report": "This is a formal report. Preserve structure, headings logic, and factual precision. Keep the tone authoritative.",
60
+ }
61
 
62
  PROMPTS = {
63
  "simple": SIMPLE_PROMPT,
 
66
  }
67
 
68
 
69
+ async def humanize_text(
70
+ text: str,
71
+ mode: str = "standard",
72
+ readability: str = "neutral",
73
+ purpose: str = "professional",
74
+ ) -> str:
75
  api_key = os.getenv("GROQ_API_KEY")
76
  if not api_key:
77
  raise ValueError("GROQ_API_KEY not set in environment variables.")
78
 
79
  client = Groq(api_key=api_key)
80
+
81
+ # Build the system prompt by combining mode + readability + purpose
82
+ base_prompt = PROMPTS.get(mode, STANDARD_PROMPT)
83
+ readability_mod = READABILITY_MODIFIERS.get(readability.lower(), READABILITY_MODIFIERS["neutral"])
84
+ purpose_mod = PURPOSE_MODIFIERS.get(purpose.lower(), PURPOSE_MODIFIERS["professional"])
85
+
86
+ system_prompt = f"""{base_prompt}
87
+
88
+ Tone guidance: {readability_mod}
89
+
90
+ Context: {purpose_mod}"""
91
 
92
  response = client.chat.completions.create(
93
  model="llama-3.1-8b-instant",
 
95
  {"role": "system", "content": system_prompt},
96
  {"role": "user", "content": text}
97
  ],
98
+ temperature=0.85,
99
  max_tokens=2000,
100
  )
101
 
main.py CHANGED
@@ -27,10 +27,14 @@ app.add_middleware(
27
  class HumanizeRequest(BaseModel):
28
  text: str
29
  mode: str = "standard"
 
 
30
 
31
  class HumanizeResponse(BaseModel):
32
  humanized: str
33
  mode: str
 
 
34
 
35
  @app.post("/humanize", response_model=HumanizeResponse)
36
  async def humanize(request: HumanizeRequest):
@@ -40,8 +44,18 @@ async def humanize(request: HumanizeRequest):
40
  detail="mode must be one of: simple, standard, enhanced"
41
  )
42
  try:
43
- humanized_text = await humanize_text(request.text, mode=request.mode)
44
- return HumanizeResponse(humanized=humanized_text, mode=request.mode)
 
 
 
 
 
 
 
 
 
 
45
  except Exception as e:
46
  import traceback
47
  raise HTTPException(status_code=500, detail=traceback.format_exc())
 
27
  class HumanizeRequest(BaseModel):
28
  text: str
29
  mode: str = "standard"
30
+ readability: str = "neutral"
31
+ purpose: str = "professional"
32
 
33
  class HumanizeResponse(BaseModel):
34
  humanized: str
35
  mode: str
36
+ readability: str
37
+ purpose: str
38
 
39
  @app.post("/humanize", response_model=HumanizeResponse)
40
  async def humanize(request: HumanizeRequest):
 
44
  detail="mode must be one of: simple, standard, enhanced"
45
  )
46
  try:
47
+ humanized_text = await humanize_text(
48
+ request.text,
49
+ mode=request.mode,
50
+ readability=request.readability,
51
+ purpose=request.purpose,
52
+ )
53
+ return HumanizeResponse(
54
+ humanized=humanized_text,
55
+ mode=request.mode,
56
+ readability=request.readability,
57
+ purpose=request.purpose,
58
+ )
59
  except Exception as e:
60
  import traceback
61
  raise HTTPException(status_code=500, detail=traceback.format_exc())