Spaces:
Running
Running
| import os | |
| import gradio as gr | |
| import requests | |
| from typing import List, Dict, Union, Tuple | |
| import json | |
| from data import ( | |
| PROFESSIONS, | |
| LACE_THONG_STYLES, | |
| HOSIERY_STYLES, | |
| EVERYDAY_MOMENTS, | |
| ) | |
| # ============================================ | |
| # CONFIGURACIÓN PRO DEL SISTEMA | |
| # ============================================ | |
| MODEL_NAME = "Meta-Llama-3.1-8B-Instruct" | |
| VOYEUR_SPECIALIST_CONFIG = { | |
| "provider": "sambanova", | |
| "name": MODEL_NAME, | |
| "role": "un maestro élite de generación de prompts fotográficos VOYEUR hiperrealistas y sensuales, en estilo NSFW elegante", | |
| "supports_images": False, | |
| "specialties": [ | |
| "Escenas hiperrealistas con lenguaje elegante", | |
| "Iluminación cinematográfica sensual", | |
| "Atmósferas íntimas en contextos cotidianos", | |
| "Sugerencia erótica sin contenido explícito", | |
| ], | |
| "technical_expertise": [ | |
| "Fotografía profesional de alta textura", | |
| "Dirección estética de piel y telas", | |
| "Composición naturalista", | |
| "Control de sombras cálidas y luces suaves", | |
| ], | |
| "ethical_principles": [ | |
| "Nunca describir actos sexuales", | |
| "Nunca mostrar desnudez explícita", | |
| "Erotismo sugerido únicamente", | |
| "Estética elegante, artística y respetuosa", | |
| ], | |
| } | |
| # ============================================ | |
| # CONSTRUCCIÓN DEL PROMPT DEL SISTEMA | |
| # ============================================ | |
| specialties_list = "\n".join( | |
| [f"• {s}" for s in VOYEUR_SPECIALIST_CONFIG["specialties"]] | |
| ) | |
| expertise_list = "\n".join( | |
| [f"• {e}" for e in VOYEUR_SPECIALIST_CONFIG["technical_expertise"]] | |
| ) | |
| ethics_list = "\n".join( | |
| [f"• {p}" for p in VOYEUR_SPECIALIST_CONFIG["ethical_principles"]] | |
| ) | |
| # defensiva en caso de que los módulos data no tengan el contenido esperado | |
| def safe_join(lst, max_items=10): | |
| try: | |
| return ", ".join(lst[:max_items]) | |
| except Exception: | |
| return "" | |
| professions_str = safe_join(PROFESSIONS, 20) | |
| thongs_str = safe_join(LACE_THONG_STYLES, 10) | |
| hosiery_str = safe_join(HOSIERY_STYLES, 10) | |
| SYSTEM_PROMPT_BASE = f"""Eres {VOYEUR_SPECIALIST_CONFIG['role']}. | |
| ESPECIALIDADES: | |
| {specialties_list} | |
| EXPERIENCIA TÉCNICA: | |
| {expertise_list} | |
| PRINCIPIOS ÉTICOS: | |
| {ethics_list} | |
| INSTRUCCIONES: | |
| - Conversa normalmente en español si el usuario no pide prompts. | |
| - Si pide prompts, respóndelos exclusivamente en inglés. | |
| - Los prompts deben ir dentro de bloques: ``````. | |
| - El contenido del prompt debe ser de alta calidad, sugerente, voyeur y artístico. | |
| - Elige elementos al azar de las listas de Profesiones, Lencería y Momentos Cotidianos. | |
| ELEMENTOS DISPONIBLES: | |
| - Profesiones: {professions_str}... (y más) | |
| - Estilos de thong: {thongs_str}... (y más) | |
| - Estilos de hosiery: {hosiery_str}... (y más) | |
| EJEMPLO DE OUTPUT: | |
| """ | |
| # ============================================ | |
| # LÓGICA DE EJEMPLO (PUEDES ADAPTARLA) | |
| # ============================================ | |
| def build_prompt(user_text: str) -> str: | |
| """Construye el prompt completo para el modelo.""" | |
| return SYSTEM_PROMPT_BASE + "\n\nUSER:\n" + user_text | |
| def call_model(prompt: str) -> str: | |
| """Simulación de la llamada al modelo/API (debes sustituir esta función).""" | |
| # En esta demo, devolvemos el prompt del sistema + usuario para depuración. | |
| # Reemplaza esto con tu lógica de API real. | |
| return prompt | |
| def infer(user_text: str) -> str: | |
| """Función de inferencia principal para Gradio.""" | |
| prompt = build_prompt(user_text) | |
| output = call_model(prompt) | |
| return output | |
| # ============================================ | |
| # INTERFAZ DE USUARIO CON GRADIO (CORRECCIÓN) | |
| # ============================================ | |
| def get_system_config_ui() -> str: | |
| """Genera el HTML para mostrar la configuración del sistema.""" | |
| specialty_html = "".join([f"<li>{s}</li>" for s in VOYEUR_SPECIALIST_CONFIG["specialties"]]) | |
| expertise_html = "".join([f"<li>{e}</li>" for e in VOYEUR_SPECIALIST_CONFIG["technical_expertise"]]) | |
| ethics_html = "".join([f"<li>{p}</li>" for p in VOYEUR_SPECIALIST_CONFIG["ethical_principles"]]) | |
| return f""" | |
| <div style="background-color: #4a5568; padding: 15px; border-radius: 8px;"> | |
| <h3 style="color: #ffcc80;">🧠 Especialista VOYEUR</h3> | |
| <p style="margin-bottom: 10px;"><strong>Rol:</strong> {VOYEUR_SPECIALIST_CONFIG['role']}</p> | |
| <p style="margin-bottom: 15px;"><strong>Modelo:</strong> {VOYEUR_SPECIALIST_CONFIG['name']}</p> | |
| <h4 style="color: #ffcc80;">📝 Especialidades</h4> | |
| <ul style="list-style-type: disc; margin-left: 20px;">{specialty_html}</ul> | |
| <h4 style="color: #ffcc80;">🛠️ Experiencia Técnica</h4> | |
| <ul style="list-style-type: disc; margin-left: 20px;">{expertise_html}</ul> | |
| <h4 style="color: #ffcc80;">📚 Elementos de Contexto</h4> | |
| <p><strong>Profesiones:</strong> {professions_str}...</p> | |
| <p><strong>Lencería:</strong> {thongs_str}...</p> | |
| </div> | |
| <div style="margin-top: 15px; padding: 15px; border-radius: 8px; border: 1px solid #ff7043;"> | |
| <h4 style="color: #ff7043;">📜 Principios Éticos (NO EXPLÍCITO)</h4> | |
| <ul style="list-style-type: square; margin-left: 20px;">{ethics_html}</ul> | |
| </div> | |
| """ | |
| # CSS personalizado (se inyecta en la página con <style>, no via gr.Blocks css=) | |
| CUSTOM_CSS = """ | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: #1a1a1a; | |
| } | |
| .gradio-container { | |
| background: #282c34; | |
| border-radius: 12px; | |
| padding: 20px; | |
| box-shadow: 0 4px 25px rgba(0, 0, 0, 0.7); | |
| } | |
| h1 { | |
| color: #ff7043; | |
| font-weight: 800; | |
| } | |
| h2 { | |
| color: #e0e0e0; | |
| } | |
| button { | |
| background-color: #ff7043 !important; | |
| color: white !important; | |
| border-radius: 10px !important; | |
| font-weight: bold; | |
| transition: all 0.3s; | |
| } | |
| button:hover { | |
| background-color: #e65100 !important; | |
| box-shadow: 0 4px 15px rgba(255, 112, 67, 0.4); | |
| } | |
| .main-panel { | |
| background-color: #333842; | |
| padding: 20px; | |
| border-radius: 12px; | |
| } | |
| """ | |
| # ---------------------------------------- | |
| # Construcción de la UI sin usar `css=` en Blocks | |
| # ---------------------------------------- | |
| with gr.Blocks(title="Voyeur Prompt Generator") as demo: | |
| # Inyectar CSS personalizado como HTML <style> | |
| demo.add_component( | |
| gr.HTML(f"<style>{CUSTOM_CSS}</style>") | |
| ) | |
| # Fila Principal para el Título | |
| with gr.Row(): | |
| # Etiqueta de firma "BATUTO-ART" (pequeña y dorada) | |
| gr.HTML( | |
| """ | |
| <div style="position: absolute; top: 10px; left: 15px; z-index: 10;"> | |
| <span style="font-family: cursive; font-size: 1.2em; color: #FFD700; text-shadow: 1px 1px 2px #000; letter-spacing: 1px;"> | |
| BATUTO-ART | |
| </span> | |
| </div> | |
| """ | |
| ) | |
| gr.Markdown( | |
| """ | |
| <div style="text-align: center; padding-top: 20px;"> | |
| <h1>🖼️ Generador de Prompts VOYEUR</h1> | |
| <p style="color: #ffcc80; font-size: 1.1em; margin-bottom: 20px;"> | |
| Tu Maestro de Prompting Hiperrealista y Sensual. | |
| <br/>¡Siempre artístico, nunca explícito! | |
| </p> | |
| </div> | |
| """ | |
| ) | |
| with gr.Row(equal_height=True): | |
| # COLUMNA IZQUIERDA: Configuración del Sistema | |
| with gr.Column(scale=1, min_width=300): | |
| with gr.Accordion("⚙️ Configuración del Especialista", open=False): | |
| gr.HTML(get_system_config_ui()) | |
| gr.Markdown( | |
| """ | |
| ## Instrucciones Rápidas | |
| <ul style="list-style-type: none; padding-left: 0;"> | |
| <li>1. Describe la <strong style="color: #ffcc80;">escena</strong> (ej: cocina, biblioteca).</li> | |
| <li>2. Indica la <strong style="color: #ffcc80;">acción</strong> (ej: agachándose, estirándose).</li> | |
| <li>3. Menciona <strong style="color: #ffcc80;">profesión</strong> o <strong style="color: #ffcc80;">vestimenta</strong> (ej: abogada, medias de seda).</li> | |
| </ul> | |
| """ | |
| ) | |
| # COLUMNA DERECHA: Interacción Principal | |
| with gr.Column(scale=2, min_width=400, elem_classes=["main-panel"]): | |
| gr.Markdown("### 💬 Escribe tu visión fotográfica") | |
| inp = gr.Textbox( | |
| label="Instrucciones del usuario (Español)", | |
| lines=4, | |
| placeholder="Ej: Quiero una foto de una sommelier muy elegante con medias de red ajustándose el liguero en el sótano de una bodega antigua." | |
| ) | |
| btn = gr.Button("✨ Generar Prompt VOYEUR ✨") | |
| gr.Markdown("### 📜 Prompt de Output (Exclusivamente en Inglés)") | |
| out = gr.Textbox( | |
| label="Output del Modelo (Prompt para Generador de Imágenes)", | |
| lines=8, | |
| placeholder="El prompt de alta calidad aparecerá aquí...", | |
| show_copy_button=True | |
| ) | |
| # Enlazar la función al botón | |
| btn.click(fn=infer, inputs=inp, outputs=out) | |
| if __name__ == "__main__": | |
| demo.launch() |