# -*- coding: utf-8 -*- """ app.py Interfaz de usuario mística (Frontend) basada en Gradio para Fénix Aprendiz. Incluye el Bot de Inquietudes Humanas: una "preparación del oráculo" que sube automáticamente +1 nivel por día (tope 100) y genera 10 inquietudes diarias, rotando entre categorías (miedos existenciales, crisis de fe, propósito de vida, debates bíblicos, consejo espiritual, alma y más allá) con profundidad creciente según el nivel, sin repetir temas recientes. Compatible con todas las versiones de Gradio (sin type="messages" ni parámetros experimentales). """ import os import time import threading from datetime import datetime, timedelta import gradio as gr import fenix_core # Importamos para inyectar voces místicas de forma dinámica from fenix_core import ( ciclo_completo, procesar_pdf, generar_voz, guardar_conversacion, cargar_conversaciones, revisar_conversaciones_pendientes, actualizar_claves_dinamicas, llamar_cerebras_directo, rotar_clave_cerebras_fallida, CEREBRAS_KEYS_POOL, NVIDIA_KEYS_POOL, describir_imagen, generar_imagen_ia, cargar_galeria_imagenes, texto_biblioteca, borrar_libro, listar_libros, guardar_gratitud, listar_gratitudes, guardar_historia, listar_historias, ) from fenix_progreso import obtener_progreso, registrar_pregunta from gradio_theme_fenix import apply_fenix_theme, FENIX_CSS, fenix_header, fenix_footer SUFIJO_MAESTRO = "\n\n_(maestro:" # El orbe se acelera al enviar y vuelve solo a su ritmo normal a los 14s. # FIX CRÍTICO: cuando 'js' y 'fn' van en el MISMO evento con 'inputs' definidos, # Gradio pasa esos inputs como argumentos a la función JS y usa lo que ELLA # devuelva como los valores reales que llegan a 'fn'. La versión anterior no # aceptaba ni devolvía nada, así que Gradio mandaba 'undefined' (-> None) en # vez del mensaje real, y por eso 'responder()' recibía mensaje=None y petaba. # Ahora la JS recibe (mensaje, historial, voz) y los devuelve TAL CUAL, usando # la función solo para el efecto visual como efecto secundario. JS_ORBE_PENSANDO = """ (mensaje, historial, voz) => { const orbe = document.querySelector('.orbe-luz'); if (orbe) { orbe.classList.add('orbe-pensando'); setTimeout(() => orbe.classList.remove('orbe-pensando'), 14000); } return [mensaje, historial, voz]; } """ # Analizador de volumen real de la voz de Fénix (Web Audio API), inyectado UNA # vez en con demo.launch(head=...) para que sobreviva a que Gradio # reemplace el