Batuto_VOY_IA / app.py
BATUTO-ART's picture
Update app.py
12aa591 verified
raw
history blame
9.75 kB
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)