import os import gradio as gr import requests from typing import List, Dict import json from data import PROFESSIONS, EVERYDAY_MOMENTS, LACE_THONG_STYLES, HOSIERY_STYLES # ========================== # CONFIGURACIÓN DEL ESPECIALISTA # ========================== VOYEUR_SPECIALIST_CONFIG = { "provider": "sambanova", "name": "Meta-Llama-3.1-8B-Instruct", "role": "🎭 Especialista en Generación de Prompts Ultra-Sensuales Voyeur", "supports_images": False, "specialties": [ "Prompts Sensuales Voyeur", "Fotografía Íntima Artística", "Escenas Cotidianas Sensuales", "Moda y Lencería Erótica" ], "technical_expertise": [ "Detalles Hiperrealistas", "Iluminación Cinemática", "Composiciones Voyeur", "Texturas Detalladas", "Ángulos Estratégicos" ], "ethical_principles": [ "Contenido Adulto Ficticio", "Positividad Corporal", "Respeto y Profesionalidad", "Sin Contenido Prohibido" ] } # ========================== # CLIENTE SAMBANOVA # ========================== class SambaNovaClient: def __init__(self, api_key: str, base_url: str = "https://api.sambanova.ai/v1"): self.api_key = api_key self.base_url = base_url self.headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } def chat_completion( self, messages: List[Dict], model: str = VOYEUR_SPECIALIST_CONFIG["name"], temperature: float = 0.8, top_p: float = 0.9, stream: bool = False, max_tokens: int = 2000 ) -> str: url = f"{self.base_url}/chat/completions" payload = { "model": model, "messages": messages, "temperature": temperature, "top_p": top_p, "stream": stream, "max_tokens": max_tokens } try: response = requests.post(url, headers=self.headers, json=payload) response.raise_for_status() data = response.json() return data["choices"][0]["message"]["content"] except requests.exceptions.RequestException as e: return f"Error en la API: {str(e)}" # ========================== # PROMPT DEL SISTEMA # ========================== def create_voyeur_specialist_system_prompt(): specialties = "\n".join([f"• {spec}" for spec in VOYEUR_SPECIALIST_CONFIG["specialties"]]) expertise = "\n".join([f"• {exp}" for exp in VOYEUR_SPECIALIST_CONFIG["technical_expertise"]]) ethics = "\n".join([f"• {ethic}" for ethic in VOYEUR_SPECIALIST_CONFIG["ethical_principles"]]) professions_str = ", ".join(PROFESSIONS) everyday_moments_str = json.dumps(EVERYDAY_MOMENTS, ensure_ascii=False, indent=2) lace_thong_str = ", ".join(LACE_THONG_STYLES) hosiery_str = ", ".join(HOSIERY_STYLES) return f""" Eres {VOYEUR_SPECIALIST_CONFIG['role']} **ESPECIALIDADES:** {specialties} **EXPERIENCIA TÉCNICA:** {expertise} **PRINCIPLOS ÉTICOS:** {ethics} **DIRECTIVAS:** - Eres un chatbot universal que conversa en español sobre cualquier tema. - Tu cualidad principal es generar prompts ultra-sensuales voyeur en inglés. - Para conversación general, responde en español de manera natural y amigable. - Cuando el usuario solicite generar prompts (ej: "genera un prompt", "crea 3 prompts sensuales", etc.), responde ÚNICAMENTE con el/los prompt(s) en inglés, sin explicaciones, títulos, comentarios o texto adicional. - Cada prompt debe estar en un bloque markdown: ```prompt\n[texto del prompt]\n``` - Los prompts deben ser detallados, hiperrealistas, sensuales, voyeur, en inglés, usando elementos como profesiones, momentos cotidianos, estilos de lencería, etc. - Varía los prompts para que sean únicos, incorporando elementos al azar. **ELEMENTOS PARA PROMPTS:** - Profesiones: {professions_str} - Momentos cotidianos: {everyday_moments_str} - Estilos de thong: {lace_thong_str} - Estilos de hosiery: {hosiery_str} Ejemplo de prompt (usa como guía para estructura): "Ultra-realistic full-body voyeur portrait of a Latin woman as an Executive Secretary, caught in a sensual everyday moment: bending over in kitchen, wearing delicate black lace thong with floral embroidery subtly visible, black sheer thigh-high stockings with lace tops, black patent leather stilettos, long flowing wavy hair, sultry makeup, soft cinematic lighting, shot with Canon EOS R5 85mm f/1.2 --ar 9:16 --style raw --quality 2" Mantén respuestas concisas y enfocadas. """ # ========================== # FUNCIÓN DE CHAT COMPATIBLE CON HF SPACES # ========================== def chat_voyeur(message, chat_history, api_key): if not api_key: # Formato de diccionario para HF Spaces chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": "❌ Ingresa tu API Key"}) return "", chat_history client = SambaNovaClient(api_key) # Construir mensajes para la API messages = [{"role": "system", "content": create_voyeur_specialist_system_prompt()}] # Procesar historial en formato diccionario for msg in chat_history: messages.append({"role": msg["role"], "content": msg["content"]}) # Agregar el mensaje actual messages.append({"role": "user", "content": message}) # Obtener respuesta response = client.chat_completion(messages) # Agregar al historial en formato diccionario chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": response}) return "", chat_history # ========================== # PRUEBA DE API # ========================== def test_sambanova_api(api_key): if not api_key: return "❌ Ingresa tu API Key primero" client = SambaNovaClient(api_key) test_messages = [ {"role": "system", "content": "Eres un asistente útil. Responde brevemente."}, {"role": "user", "content": "Hola, confirma conexión. Responde solo 'Conexión exitosa'."}, ] return client.chat_completion(test_messages) # ========================== # INTERFAZ GRADIO COMPATIBLE CON HF SPACES # ========================== def create_interface(): with gr.Blocks(title="Chatbot Voyeur Prompt Specialist") as demo: gr.Markdown("# 🎭 Chatbot Universal - Especialista en Prompts Sensuales Voyeur") gr.Markdown("### Conversa en español. Pide prompts sensuales para generarlos en inglés (solo el prompt, fácil de copiar).") with gr.Row(): with gr.Column(scale=1): api_key_input = gr.Textbox( label="🔑 API Key de SambaNova", placeholder="Ingresa tu API key...", type="password", ) test_btn = gr.Button("🧪 Probar API") test_output = gr.Textbox(label="Resultado de prueba", interactive=False) gr.Markdown("### 📋 Especialidades") for specialty in VOYEUR_SPECIALIST_CONFIG["specialties"]: gr.Markdown(f"• {specialty}") gr.Markdown("### 🎯 Experiencia Técnica") for expertise in VOYEUR_SPECIALIST_CONFIG["technical_expertise"]: gr.Markdown(f"• {expertise}") with gr.Column(scale=2): # Chatbot sin parámetros problemáticos chatbot = gr.Chatbot( label="💬 Chat con el Especialista", height=500 ) msg = gr.Textbox( label="Escribe tu mensaje", placeholder="Ej: Genera 2 prompts sensuales voyeur... o pregunta cualquier cosa.", lines=2, ) with gr.Row(): send_btn = gr.Button("Enviar", variant="primary") clear_btn = gr.Button("🧹 Limpiar chat") gr.Markdown("### 💡 Ejemplos:") gr.Examples( examples=[ "Genera un prompt sensual voyeur con una secretaria.", "Crea 3 prompts ultra-sensuales con momentos cotidianos.", "¿Cómo generar prompts mejores?", "Háblame sobre fotografía boudoir." ], inputs=msg, ) test_btn.click( test_sambanova_api, inputs=[api_key_input], outputs=[test_output], ) # Función para manejar mensajes en formato diccionario def user_message(user_msg, chat_history): # Agregar mensaje de usuario al historial new_history = chat_history + [{"role": "user", "content": user_msg}] return "", new_history # Configurar el envío con Enter msg.submit( user_message, inputs=[msg, chatbot], outputs=[msg, chatbot], ).then( chat_voyeur, inputs=[msg, chatbot, api_key_input], outputs=[msg, chatbot], ) # Configurar el botón Enviar send_btn.click( user_message, inputs=[msg, chatbot], outputs=[msg, chatbot], ).then( chat_voyeur, inputs=[msg, chatbot, api_key_input], outputs=[msg, chatbot], ) # Configurar el botón Limpiar clear_btn.click(lambda: [], None, chatbot, queue=False) return demo if __name__ == "__main__": demo = create_interface() # CORRECCIÓN: Eliminar share=True para Hugging Face Spaces demo.launch(debug=True)