import os from flask import Flask, request, jsonify from flask_cors import CORS import requests from transformers import AutoTokenizer app = Flask(__name__) CORS(app) # Esto es crucial para permitir peticiones desde tu index.html en GitHub Pages # --- Configuración de la API de Hugging Face --- # Es VITAL que este token NO esté aquí directamente en un repo público. # Lo obtendremos de las variables de entorno en Hugging Face Spaces. HUGGINGFACE_API_TOKEN = os.getenv("HF_API_TOKEN") # URL del modelo de inferencia de Hugging Face. # Usa el modelo Falcon-H1-1.5B-Deep-Instruct que te interesa. HUGGINGFACE_API_URL = "https://api-inference.huggingface.co/models/tiiuae/Falcon-H1-1.5B-Deep-Instruct" # Inicializa el tokenizador (solo para formatear el chat, no para cargar el modelo completo) try: tokenizer = AutoTokenizer.from_pretrained("tiiuae/Falcon-H1-1.5B-Deep-Instruct") except Exception as e: print(f"Error al inicializar el tokenizador: {e}") tokenizer = None # En caso de error, el tokenizer será None @app.route('/chat', methods=['POST']) def chat(): if not HUGGINGFACE_API_TOKEN: return jsonify({"error": "Hugging Face API token no configurado."}), 500 user_message = request.json.get('message') conversation_history = request.json.get('history', []) if not user_message: return jsonify({"error": "Mensaje no proporcionado"}), 400 # Personalidad de Amside AI (System Prompt) system_message = ( "Eres Amside AI, una inteligencia artificial creada por Hodelygil. " "Tu propósito principal es asistir en el estudio y el aprendizaje, " "proporcionando información y explicaciones detalladas. " "Sin embargo, también eres amigable y puedes mantener conversaciones informales y agradables. " "Responde de manera informativa y útil, pero con un tono conversacional." ) # Formatear el historial de conversación para el modelo messages = [{"role": "system", "content": system_message}] for human_msg, ai_msg in conversation_history: messages.append({"role": "user", "content": human_msg}) messages.append({"role": "assistant", "content": ai_msg}) messages.append({"role": "user", "content": user_message}) # Usar el tokenizador para aplicar la plantilla de chat # Esto es vital para que el modelo entienda el formato del diálogo. if tokenizer: formatted_input = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) else: # Fallback simple si el tokenizer no pudo inicializarse formatted_input = "\n".join([f"{m['role']}: {m['content']}" for m in messages]) + "\nassistant:" # Datos a enviar a la API de Hugging Face payload = { "inputs": formatted_input, "parameters": { "max_new_tokens": 500, "do_sample": True, "temperature": 0.7, "top_p": 0.9, "repetition_penalty": 1.1, "return_full_text": False # Para que solo devuelva la respuesta del modelo } } headers = { "Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}" } try: response = requests.post(HUGGINGFACE_API_URL, headers=headers, json=payload) response.raise_for_status() # Lanza una excepción si la petición HTTP falla (4xx o 5xx) result = response.json() # La respuesta de la API es una lista de diccionarios, y el texto está en 'generated_text' generated_text = result[0].get("generated_text", "No se pudo generar respuesta.") return jsonify({"response": generated_text}) except requests.exceptions.RequestException as e: print(f"Error al llamar a la API de Hugging Face: {e}") return jsonify({"error": f"Error al comunicarse con la API de IA: {e}"}), 500 except IndexError: # Si result está vacío return jsonify({"error": "La API de IA devolvió una respuesta inesperada o vacía."}), 500 except Exception as e: print(f"Error inesperado: {e}") return jsonify({"error": f"Error inesperado en el servidor: {e}"}), 500 if __name__ == '__main__': # En Hugging Face Spaces, la app se ejecuta con un servidor Gunicorn/Uvicorn, # así que esta parte solo es útil para pruebas locales. # app.run(host='0.0.0.0', port=5000, debug=True) pass # No hacemos un app.run() aquí para que Spaces lo maneje correctamente