Batuto_VOY_IA / app.py
BATUTO-ART's picture
Update app.py
28ab90e verified
raw
history blame
9.31 kB
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()