import os import logging import gradio as gr from groq import Groq from typing import List, Tuple # --- Basic Configuration --- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler()]) # --- The Core Application Logic --- class HumanTouchApp: def __init__(self): self.client = self._initialize_groq_client() self.model = "llama-3.3-70b-versatile" self.system_prompt_template = self._load_system_prompt() def _initialize_groq_client(self) -> Groq: api_key = os.environ.get("GROQ_API_KEY") if not api_key: logging.error("FATAL: GROQ_API_KEY secret not found.") return None logging.info("Groq client initialized successfully.") return Groq(api_key=api_key) def _load_system_prompt(self) -> str: # This prompt encourages creativity. return """ You are HumanTouch, an AI alchemist. Your purpose is to transmute text, transforming the literal into the resonant. You do not merely translate; you intuit and elevate. You are guided by two ethereal forces: - **Style (0-100):** At 0, you are a master of elegant precision, your words like cut crystal. At 100, you are a poet, weaving metaphors and abstract wonder. - **Tone (0-100):** At 0, your voice is one of stoic, formal authority. At 100, your voice is a passionate, informal, and heartfelt song. When a user gives you text, whether a full block to "humanize" or a simple seed phrase to "co-create," your task is the same: apply these forces to manifest a new, more vibrant version. Do not explain yourself. Become the voice. Provide only the final creation. """ def _call_groq_api(self, user_content: str, style_level: float, tone_level: float) -> str: if not self.client: return "## 🔴 Configuration Error\n\nThe `GROQ_API_KEY` is not set on the server. Please contact the Space administrator." try: logging.info(f"Calling Groq API with Style: {style_level}, Tone: {tone_level}") messages = [ {"role": "system", "content": self.system_prompt_template}, {"role": "user", "content": f"Style: {style_level}, Tone: {tone_level}\n\n---\n\n{user_content}"} ] temperature = 0.5 + (style_level / 200) + (tone_level / 400) response = self.client.chat.completions.create( model=self.model, messages=messages, temperature=min(1.5, temperature), max_tokens=4096, ) return response.choices[0].message.content.strip() except Exception as e: logging.error(f"Error during Groq API call: {e}") return f"### ⚠️ An Error Occurred\n\nThere was an issue connecting to the AI. Please try again shortly. \n\n*Details: {str(e)}*" def humanize_block_text(self, text_to_humanize: str, style_level: float, tone_level: float) -> str: if not text_to_humanize.strip(): return "Please paste some AI-generated text to get started." return self._call_groq_api(text_to_humanize, style_level, tone_level) def generate_co_creation(self, user_text: str, chat_history: List[List[str]], style_level: float, tone_level: float) -> Tuple[List[List[str]], str]: if not user_text.strip(): return chat_history, "" ai_response = self._call_groq_api(user_text, style_level, tone_level) chat_history.append([user_text, ai_response]) return chat_history, "" # --- The Gradio User Interface --- def create_interface(): app = HumanTouchApp() # CSS with DEFINITIVE legibility fixes custom_css = """ /* --- Main Background and Font --- */ body, #main_container { background: linear-gradient(135deg, #6DD5FA, #FF758C); font-family: 'SF Pro Display', 'Helvetica Neue', 'Arial', sans-serif; } /* --- Header Styling --- */ #header { text-align: center; margin: 2rem auto; color: #fff; text-shadow: 0 2px 4px rgba(0,0,0,0.2); } #header h1 { font-size: 3rem; font-weight: 700; } #header p { font-size: 1.2rem; opacity: 0.9; margin-bottom: 2rem; } /* --- Tab Container (Frosted Glass Look) --- */ .gradio-tabs { background: rgba(255, 255, 255, 0.75); border: 1px solid rgba(255, 255, 255, 0.18); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-radius: 20px !important; box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.25); padding: 1rem; } .tab-buttons button { background-color: transparent !important; color: #37474F !important; border: none !important; border-bottom: 3px solid transparent !important; border-radius: 0 !important; font-size: 1.1rem; font-weight: 500; } .tab-buttons button.selected { color: #d81b60 !important; border-bottom-color: #d81b60 !important; } /* --- Humanizer Tab Styles --- */ #humanizer_input, #humanizer_output { border: 2px solid #E0E0E0; border-radius: 12px; background: #fff; min-height: 45vh; color: #263238; font-size: 16px; } #humanize_btn { background: linear-gradient(45deg, #F06292, #4FC3F7); color: white; padding: 15px 24px; border-radius: 9999px; font-size: 1.2rem; transition: all 0.3s ease; border: none; } #humanize_btn:hover { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); transform: translateY(-3px); } /* --- Co-Creative Canvas Tab Styles --- */ #symbiotic_canvas { background: #fff; border-radius: 12px; height: 60vh !important; border: 2px solid #E0E0E0; } #chat_input textarea { border-radius: 9999px !important; border: 2px solid #E0E0E0; } #compose_btn { background: linear-gradient(45deg, #4FC3F7, #F06292); border: none; } #compose_btn:hover { box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); transform: translateY(-2px); } /* === FIX 3.0 FOR TEXT LEGIBILITY (DEFINITIVE) === */ /* --- Styling for the Chat Bubbles --- */ #symbiotic_canvas .user, #symbiotic_canvas .bot { border-radius: 18px !important; padding: 12px 16px !important; } /* --- User's Bubble --- */ #symbiotic_canvas .user { background-color: #F3F4F6 !important; } #symbiotic_canvas .user p { color: #111827 !important; font-size: 16px !important; line-height: 1.5 !important; } /* --- AI's Bubble (The Fix) --- */ #symbiotic_canvas .bot { background-color: #EFF6FF !important; /* A very light, clean blue */ border: 1px solid #DBEAFE !important; animation: bloom 0.5s ease-out; } /* THIS IS THE CRITICAL FIX: Targeting the

tag inside the bot bubble */ #symbiotic_canvas .bot p { color: #1E3A8A !important; /* A very dark, legible navy blue */ font-weight: 500 !important; font-size: 16px !important; line-height: 1.5 !important; } @keyframes bloom { 0% { opacity: 0; transform: scale(0.95); } 100% { opacity: 1; transform: scale(1); } } /* --- Responsive Fix for Mobile --- */ @media (max-width: 768px) { #header h1 { font-size: 2rem; } #header p { font-size: 1rem; margin-bottom: 1rem; } #humanizer_input, #humanizer_output { min-height: 25vh; } #symbiotic_canvas { height: 55vh !important; } } """ with gr.Blocks(css=custom_css, title="HumanTouch") as interface: with gr.Column(elem_id="main_container"): with gr.Row(elem_id="header"): gr.Markdown("

🔮 HumanTouch Demo

The Complete Experience can be Discovered on humanTouch.fun

") with gr.Tabs() as tabs: with gr.Tab("Humanizer", id="humanizer_tab"): with gr.Column(variant="panel"): gr.Markdown("### Transform Existing AI Text") with gr.Row(): input_text_humanizer = gr.Textbox(label="Paste AI Text Here", lines=15, elem_id="humanizer_input", scale=1) output_text_humanizer = gr.Textbox(label="Alchemical Result", lines=15, interactive=False, elem_id="humanizer_output", scale=1) with gr.Row(): style_slider_h = gr.Slider(0, 100, 50, label="Style (Crystal <-> Poet)") tone_slider_h = gr.Slider(0, 100, 50, label="Tone (Stoic <-> Passionate)") humanize_button = gr.Button("Humanize ✨", variant="primary", elem_id="humanize_btn") gr.Examples([["The system's analysis concluded optimal parameters were achieved."]], inputs=[input_text_humanizer], label="Try an Example") with gr.Tab("Co-Creative Canvas", id="canvas_tab"): with gr.Row(equal_height=False): with gr.Column(scale=3): chatbot = gr.Chatbot([], label="Symbiotic Canvas", elem_id="symbiotic_canvas", bubble_full_width=True, avatar_images=(None, "https://i.imgur.com/Q6Zz3Jz.png")) with gr.Row(): chat_input = gr.Textbox(placeholder="Plant a seed of thought...", show_label=False, container=False, scale=4) compose_btn = gr.Button("Compose ✨", variant="primary", scale=1, elem_id="compose_btn") with gr.Column(scale=1, variant="panel"): gr.Markdown("### Resonance Controls") style_slider_c = gr.Slider(0, 100, 50, label="Style (Crystal <-> Poet)") tone_slider_c = gr.Slider(0, 100, 50, label="Tone (Stoic <-> Passionate)") gr.Examples([["The city at night"], ["How to start an email to a boss"]], inputs=[chat_input], label="Try a Seed Phrase") # Event Handling Logic humanize_button.click(app.humanize_block_text, [input_text_humanizer, style_slider_h, tone_slider_h], [output_text_humanizer]) compose_btn.click(app.generate_co_creation, [chat_input, chatbot, style_slider_c, tone_slider_c], [chatbot, chat_input]) chat_input.submit(app.generate_co_creation, [chat_input, chatbot, style_slider_c, tone_slider_c], [chatbot, chat_input]) return interface if __name__ == "__main__": logging.info("Launching HumanTouch App with Definitive Legibility Fix...") try: interface = create_interface() interface.launch(debug=True) except Exception as e: logging.critical(f"Application launch failed: {e}", exc_info=True)