File size: 9,309 Bytes
6615bd0
 
 
68f4664
6615bd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cd7ff6f
6615bd0
 
 
 
 
cd7ff6f
6615bd0
 
 
 
 
cd7ff6f
 
6615bd0
 
 
cd7ff6f
6615bd0
 
cd7ff6f
 
 
 
 
 
 
 
 
6615bd0
28ab90e
 
 
 
 
 
 
 
 
 
6615bd0
c476911
6615bd0
 
27f1827
6615bd0
 
27f1827
6615bd0
 
27f1827
6615bd0
 
 
 
33af14a
6615bd0
27f1827
6615bd0
 
27f1827
 
 
6615bd0
c476911
cd7ff6f
 
 
 
 
 
 
c1f4e2d
cd7ff6f
 
 
c1f4e2d
 
 
cd7ff6f
 
 
c1f4e2d
cd7ff6f
 
 
 
c1f4e2d
28ab90e
c1f4e2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28ab90e
c1f4e2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28ab90e
 
 
 
c1f4e2d
28ab90e
 
 
 
 
c1f4e2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28ab90e
c1f4e2d
 
 
 
 
 
 
 
 
28ab90e
c1f4e2d
 
 
 
 
 
 
 
 
 
 
 
cd7ff6f
 
28ab90e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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()