Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| import asyncio | |
| from typing import Optional | |
| from PIL import Image | |
| import base64 | |
| import io | |
| import requests | |
| # --- Configuración de claves --- | |
| class Config: | |
| def __init__(self): | |
| self.SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY") | |
| self.BRIA_API_TOKEN = os.getenv("BRIA_API_TOKEN") | |
| self.validate() | |
| def validate(self): | |
| print("🔍 Verificando claves de API...") | |
| if self.SAMBANOVA_API_KEY: | |
| print("✅ SAMBANOVA_API_KEY configurada") | |
| else: | |
| print("❌ SAMBANOVA_API_KEY no encontrada") | |
| if self.BRIA_API_TOKEN: | |
| print("✅ BRIA_API_TOKEN configurado") | |
| else: | |
| print("⚠️ BRIA_API_TOKEN no configurado → generación de imágenes desactivada") | |
| config = Config() | |
| # --- Cliente SambaNova (usando SDK oficial) --- | |
| SambaNova = None | |
| sn_client = None | |
| try: | |
| from sambanova import SambaNova | |
| if config.SAMBANOVA_API_KEY: | |
| sn_client = SambaNova(api_key=config.SAMBANOVA_API_KEY) | |
| print("✅ Cliente SambaNova inicializado") | |
| except Exception as e: | |
| print(f"❌ Error al inicializar SambaNova: {e}") | |
| sn_client = None | |
| # --- Herramientas --- | |
| class AI_Tools: | |
| def __init__(self): | |
| self.sn_client = sn_client | |
| def generate_text(self, prompt: str) -> str: | |
| if not self.sn_client: | |
| return "❌ SambaNova no disponible. Verifica tu clave API." | |
| try: | |
| # ⚠️ Usa un modelo REAL de tu cuenta en SambaNova Cloud | |
| # Ejemplos comunes: "Meta-Llama-3.1-8B-Instruct", "Llama-3.2-3B-Instruct" | |
| # Reemplaza "Maverick" por un modelo válido que veas en tu dashboard | |
| response = self.sn_client.chat.completions.create( | |
| model="Meta-Llama-3.1-8B-Instruct", # ✅ CAMBIA ESTO si usas otro modelo | |
| messages=[{"role": "user", "content": prompt}], | |
| temperature=0.7, | |
| max_tokens=500 | |
| ) | |
| return response.choices[0].message.content.strip() | |
| except Exception as e: | |
| return f"❌ Error en SambaNova: {e}" | |
| def generate_image(self, prompt: str) -> Optional[Image.Image]: | |
| if not config.BRIA_API_TOKEN: | |
| return None | |
| try: | |
| url = "https://api.bria.ai/v1/generate" # ✅ sin espacio | |
| headers = {"Authorization": f"Bearer {config.BRIA_API_TOKEN}"} | |
| json_data = {"prompt": prompt, "options": {"resolution": "512x512"}} | |
| response = requests.post(url, headers=headers, json=json_data, timeout=30) | |
| if response.status_code == 200: | |
| img_b64 = response.json().get("image_base64") | |
| if img_b64: | |
| img_bytes = base64.b64decode(img_b64) | |
| return Image.open(io.BytesIO(img_bytes)) | |
| except Exception as e: | |
| print(f"⚠️ Error en Bria: {e}") | |
| return None | |
| tools = AI_Tools() | |
| # --- Procesamiento (síncrono para Gradio) --- | |
| def process_input(message: str, history: list) -> list: | |
| msg_lower = message.lower() | |
| # Generar imagen | |
| if any(kw in msg_lower for kw in ["imagen", "foto", "genera imagen", "dibuja"]): | |
| img = tools.generate_image(message) | |
| if img: | |
| return history + [(message, ("", img))] | |
| return history + [(message, "❌ No se pudo generar la imagen. ¿Tienes BRIA_API_TOKEN?")] | |
| # Generar texto con SambaNova | |
| response = tools.generate_text(message) | |
| return history + [(message, response)] | |
| # --- Interfaz Gradio --- | |
| with gr.Blocks(title="AI Assistant", theme=gr.themes.Soft()) as app: | |
| gr.Markdown("# 🤖 AI Assistant (SambaNova + Bria)") | |
| samba_status = "✅ SambaNova activo" if tools.sn_client else "❌ SambaNova inactivo" | |
| bria_status = "✅ Bria activo" if config.BRIA_API_TOKEN else "❌ Bria inactivo" | |
| gr.Markdown(f"**Estado**: {samba_status} | {bria_status}") | |
| chatbot = gr.Chatbot(height=450) | |
| msg = gr.Textbox( | |
| label="Escribe tu mensaje", | |
| placeholder="Ej: 'Explica la relatividad' o 'Genera una imagen de un dragón en Marte'", | |
| lines=2 | |
| ) | |
| gr.Examples([ | |
| "¿Qué es el aprendizaje automático?", | |
| "Genera una imagen de un bosque encantado al atardecer", | |
| "Escribe un breve cuento sobre un robot solitario" | |
| ], inputs=msg) | |
| def clear(): return [] | |
| gr.Button("Limpiar chat").click(clear, outputs=chatbot) | |
| # Con queue=True, evita bloqueos | |
| msg.submit(process_input, [msg, chatbot], chatbot, queue=True) | |
| gr.Button("Enviar").click(process_input, [msg, chatbot], chatbot, queue=True) | |
| # --- Ejecución --- | |
| if __name__ == "__main__": | |
| app.queue().launch(server_name="0.0.0.0", server_port=7860) |