Spaces:
Running
Running
| 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) |