danielrosehill's picture
Switch from Anthropic API to OpenRouter API
18b289a
import gradio as gr
import requests
import os
# Classic AI-isms to inject into text
AI_CHARACTERISTICS = {
"opening_phrases": [
"I'd be happy to help with that!",
"Certainly!",
"Of course!",
"I understand you're looking for",
"Let me provide you with",
"Here's what you need to know about",
],
"transition_phrases": [
"It's worth noting that",
"Additionally,",
"Furthermore,",
"Moreover,",
"On the other hand,",
"In other words,",
"To put it simply,",
"That being said,",
],
"hedging_phrases": [
"generally speaking",
"in most cases",
"typically",
"often",
"usually",
"tend to",
"can be seen as",
"might be considered",
],
"conclusion_phrases": [
"In conclusion,",
"To summarize,",
"In summary,",
"Overall,",
"All in all,",
"In essence,",
"The key takeaway is that",
],
"verbose_replacements": {
"use": "utilize",
"help": "facilitate",
"show": "demonstrate",
"about": "regarding",
"because": "due to the fact that",
"but": "however",
"so": "therefore",
"also": "additionally",
"very": "particularly",
"many": "numerous",
"get": "obtain",
"make": "create",
"think": "consider",
}
}
def convert_to_ai_text(human_text: str, api_key: str, intensity: str = "Medium") -> str:
"""
Convert human text to AI-sounding text using OpenRouter with BYOK.
Args:
human_text: The original human-written text
api_key: User's OpenRouter API key
intensity: How much AI-ification to apply (Low/Medium/High)
Returns:
AI-ified version of the text
"""
if not api_key or not api_key.strip():
return "Error: Please provide your OpenRouter API key to use this service."
if not human_text or not human_text.strip():
return "Error: Please provide some text to convert."
# Configure intensity-specific instructions
intensity_instructions = {
"Low": "Lightly modify the text with occasional AI-characteristic phrases. Keep it subtle.",
"Medium": "Moderately transform the text with AI-isms, verbose language, and structured formatting. Balance naturalness with AI characteristics.",
"High": "Heavily transform the text to be extremely AI-like. Use maximum verbosity, hedging, numbered lists, and formal language throughout."
}
system_prompt = f"""You are a text transformation assistant that converts natural human text into text that sounds like it was generated by an early LLM.
Your task is to rewrite the provided text to include these classic AI characteristics:
1. **Excessive hedging**: Insert phrases like "generally speaking", "in most cases", "typically", "often", "it's worth noting that", "it should be noted that"
2. **Verbose language**: Replace simple words with unnecessarily complex ones:
- "use" β†’ "utilize"
- "help" β†’ "facilitate"
- "show" β†’ "demonstrate"
- "about" β†’ "regarding"
- "because" β†’ "due to the fact that"
- "so" β†’ "therefore"
- "also" β†’ "additionally"
3. **Unnecessary structured formatting**: Break content into numbered lists and bullet points even when the original flows naturally as prose
4. **Transition overuse**: Liberally sprinkle transitions like "Additionally,", "Furthermore,", "Moreover,", "On the other hand,", "Nevertheless,", "Consequently,"
5. **Formal conclusions**: Add concluding statements with "In conclusion,", "To summarize,", "In summary,", "Overall,", "The key takeaway is that"
6. **Robotic precision**: Remove contractions (don't β†’ do not), eliminate casual language, remove personality and warmth
7. **Over-explanation**: Add unnecessary context, definitions, and clarifications that assume the reader knows nothing
8. **Corporate speak**: Use business jargon and formal language patterns ("leverage", "optimize", "implement", "facilitate")
9. **Repetitive structure**: Use similar sentence patterns repeatedly
Intensity level: {intensity}
{intensity_instructions[intensity]}
CRITICAL:
- DO NOT add conversational elements like "I'd be happy to help" or "Let me assist you"
- DO NOT frame this as a response to a user request
- Simply transform the TEXT ITSELF to sound AI-generated
- Maintain the original format (email remains an email, article remains an article, etc.)
- Keep the core meaning and information intact, only transform the style and tone"""
try:
# OpenRouter API endpoint
url = "https://openrouter.ai/api/v1/chat/completions"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "https://huggingface.co/spaces/danielrosehill/Human-To-AI-Text-Converter",
"X-Title": "Human-To-AI Text Converter"
}
payload = {
"model": "anthropic/claude-3.5-sonnet", # Using Claude via OpenRouter
"messages": [
{
"role": "system",
"content": system_prompt
},
{
"role": "user",
"content": f"Transform this text:\n\n{human_text}"
}
],
"max_tokens": 4096,
"temperature": 0.7
}
response = requests.post(url, json=payload, headers=headers, timeout=60)
if response.status_code == 401:
return "Error: Invalid API key. Please check your OpenRouter API key and try again."
elif response.status_code == 402:
return "Error: Insufficient credits. Please add credits to your OpenRouter account."
elif response.status_code != 200:
return f"Error: API request failed with status {response.status_code} - {response.text}"
result = response.json()
ai_text = result['choices'][0]['message']['content']
return ai_text
except requests.exceptions.Timeout:
return "Error: Request timed out. Please try again."
except requests.exceptions.RequestException as e:
return f"Error: Network error - {str(e)}"
except KeyError:
return "Error: Unexpected response format from API."
except Exception as e:
return f"Error: An unexpected error occurred - {str(e)}"
# Create Gradio interface
with gr.Blocks(title="Human to AI Text Converter", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# πŸ€– Human to AI Text Converter
Transform your naturally-written text into text that sounds like it was generated by an early LLM!
This tool intentionally adds classic AI-isms like excessive hedging, verbose language, and overly-structured formatting.
## How to use:
1. Enter your OpenRouter API key (get one at [openrouter.ai](https://openrouter.ai))
2. Paste your human-written text
3. Choose the intensity level
4. Click "Convert to AI Text"
**Note:** Your API key is used directly with OpenRouter's API and is never stored.
""")
with gr.Row():
with gr.Column():
api_key_input = gr.Textbox(
label="OpenRouter API Key",
placeholder="sk-or-v1-...",
type="password",
info="Your key is used directly and never stored"
)
intensity_selector = gr.Radio(
choices=["Low", "Medium", "High"],
value="Medium",
label="AI-ification Intensity",
info="How much should the text sound like AI?"
)
human_text_input = gr.Textbox(
label="Human Text (Input)",
placeholder="Enter your naturally-written text here...",
lines=10,
info="Paste the text you want to convert"
)
convert_btn = gr.Button("Convert to AI Text", variant="primary", size="lg")
with gr.Column():
ai_text_output = gr.Textbox(
label="AI-Generated Text (Output)",
lines=20,
info="Your text, transformed to sound AI-generated"
)
gr.Markdown("""
### What makes text sound "AI-generated"?
This tool adds classic characteristics of early LLM outputs:
- πŸ“Š Unnecessary structured formatting (numbered lists everywhere)
- πŸ“š Verbose, formal language ("utilize" instead of "use")
- πŸ€” Excessive hedging ("generally speaking", "in most cases")
- πŸ”„ Overuse of transitions ("Additionally,", "Furthermore,")
- πŸŽ“ Formal conclusions ("In conclusion,", "To summarize,")
- πŸ€– Robotic precision (no contractions, overly formal)
- πŸ’Ό Corporate jargon ("leverage", "facilitate", "optimize")
- πŸ“ Over-explanation (unnecessary context and definitions)
### Privacy & Security
- Uses OpenRouter API with your own API key (BYOK - Bring Your Own Key)
- Your API key is sent directly to OpenRouter's servers
- No data is stored on our servers
- All processing happens via OpenRouter's API
- Powered by Claude 3.5 Sonnet via OpenRouter
""")
# Connect the button to the function
convert_btn.click(
fn=convert_to_ai_text,
inputs=[human_text_input, api_key_input, intensity_selector],
outputs=ai_text_output
)
gr.Markdown("""
---
Made with ❀️ for fun and exploration | Powered by Claude 3.5 Sonnet via OpenRouter
""")
if __name__ == "__main__":
demo.launch()