import gradio as gr from transformers import pipeline, set_seed from helpers import generate_audio, generate_bioresonant_sigil, create_quantum_tunnel_gif, create_soul_artifact import whisper import time import os # --- INICIO DE LA OBRA --- print("Cargando el Núcleo Oracular y sus componentes...") QUANTUM_TUNNEL_PATH = create_quantum_tunnel_gif() INTRO_AUDIO = generate_audio("intro") OUTRO_AUDIO = generate_audio("outro") print("Cargando modelo de transcripción Whisper (puede tardar)...") try: whisper_model = whisper.load_model("base") whisper_loaded = True print("Whisper cargado.") except Exception as e: whisper_loaded = False print(f"Error al cargar Whisper: {e}") try: set_seed(int(time.time())) oracle = pipeline("text2text-generation", model="google/flan-t5-base", device=-1) oracle_loaded = True print("Oráculo de texto cargado.") except Exception as e: oracle_loaded = False print(f"Error al cargar el Oráculo de texto: {e}") # --- LÓGICA DEL ORÁCULO --- def query_oracle(user_echo): if not oracle_loaded: return {"title": "Error", "myth": "El Oráculo está en silencio.", "key": "Reinicia la conexión."} if not user_echo: return {"title": "Silencio", "myth": "No se ha proporcionado materia prima.", "key": "Habla o escribe tu Eco."} prompt = f""" Eres un Oráculo. Tu función es transmutar una confesión en un mito de poder. Analiza la siguiente confesión del usuario. Responde ÚNICAMENTE con un objeto JSON con tres claves: "title", "myth", "key". - "title": Crea un título épico para el mito. - "myth": Escribe un mito de transmutación de 100-150 palabras, en segunda persona ("Tú..."). Usa metáforas profundas. No des consejos. - "key": Extrae del mito una sola frase corta y poderosa. Esta es la llave resonante del usuario. Confesión del Usuario: "{user_echo}" JSON de Respuesta: """ try: response = oracle(prompt, max_length=300, num_beams=4, early_stopping=True)[0]['generated_text'] # Limpiar y parsear la respuesta JSON del modelo import json clean_json_str = response.replace("`", "").replace("json", "").strip() result = json.loads(clean_json_str) return result except Exception as e: print(f"Error parseando la respuesta del Oráculo: {e}\nRespuesta recibida: {response}") # Fallback por si el JSON falla return {"title": "Mito Incompleto", "myth": response, "key": "La forma se resistió, pero el contenido es tuyo."} def transcribe_voice(audio_path): if not whisper_loaded or audio_path is None: return "El oído del Oráculo está cerrado, por favor escribe tu Eco." try: result = whisper_model.transcribe(audio_path) return result["text"] except Exception as e: print(f"Error de transcripción: {e}") return "" # --- INTERFAZ VIVA --- css = """ @keyframes gradient-animation { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } @keyframes final-glow { 0% { box-shadow: 0 0 20px #c39cff33; } 50% { box-shadow: 0 0 40px #ffdfa099; } 100% { box-shadow: 0 0 20px #c39cff33; } } body { font-family: 'Georgia', serif; } .gradio-container { max-width: 800px !important; margin: auto; border: 1px solid #333 !important; background: linear-gradient(-45deg, #0d0d0d, #1a1224, #0d0d0d, #12241a); background-size: 400% 400%; animation: gradient-animation 15s ease infinite; transition: all 2s ease; } .final-state { background: linear-gradient(-45deg, #1a1224, #24221a, #1a1224, #241a12); background-size: 400% 400%; animation: gradient-animation 20s ease infinite, final-glow 5s ease-in-out infinite; } /* ... (otros estilos de la v3.0) ... */ .step-title { color: #c39cff; font-size: 24px; font-weight: bold; text-align: center; margin-bottom: 1rem; text-shadow: 0 0 5px #c39cff;} .step-description { color: #b0b0b0; font-size: 16px; text-align: center; margin-bottom: 2rem; line-height: 1.6;} .output-text { background-color: #1a1a1a; padding: 1rem; border-radius: 8px; border: 1px solid #333; } .gr-button { background-color: #4a4a4a; color: #e0e0e0; border: 1px solid #6a6a6a; } .gr-button:hover { background-color: #c39cff; color: #0d0d0d; border-color: #c39cff; } """ with gr.Blocks(css=css, title="Crisol 3.5: El Núcleo Oracular") as app: app_container = gr.Column(elem_classes="gradio-container") with app_container: gr.Markdown("# Crisol 3.5: El Núcleo Oracular") with gr.Column(visible=True) as step1_ui: gr.Markdown("

PASO 1: LA SINTONIZACIÓN

", elem_id="step-title") gr.Markdown("

El Crisol está vivo. Sintoniza tu psique con su resonancia. Cierra los ojos. Escucha.

", elem_id="step-description") gr.Audio(value=INTRO_AUDIO, label="Resonancia Theta (Para Introspección)", autoplay=True) next_to_step2_btn = gr.Button("Estoy sintonizado. Despertar al Oráculo.") with gr.Column(visible=False) as step2_ui: gr.Markdown("

PASO 2: LA CONFESIÓN SÓNICA

", elem_id="step-title") gr.Markdown("

Habla tu Eco. No lo pienses, siéntelo. La vibración de tu voz es la materia prima. O si lo prefieres, escribe tus palabras en el silencio.

", elem_id="step-description") voice_input = gr.Audio(sources=["microphone"], type="filepath", label="Graba tu Eco aquí:") text_input = gr.Textbox(lines=4, label="O escribe tu Eco aquí:", placeholder="La transcripción de tu voz aparecerá aquí...") next_to_tunnel_btn = gr.Button("Entregar al Crisol") with gr.Column(visible=False) as quantum_tunnel_ui: gr.Markdown("

PROCESANDO EN EL NÚCLEO

", elem_id="step-title") gr.Image(value=QUANTUM_TUNNEL_PATH, show_label=False, show_download_button=False) gr.Markdown("

El Oráculo ha escuchado. El tiempo y el espacio se pliegan. La transmutación es inminente...

", elem_id="step-description") with gr.Column(visible=False) as step3_ui: gr.Markdown("

REVELACIÓN DEL ORÁCULO

", elem_id="step-title") myth_title_output = gr.Markdown("### Título del Mito") sigil_output = gr.Image(label="Tu Sigilo Bio-Resonante", interactive=False) myth_output = gr.Textbox(label="El Mito Forjado para Ti", lines=6, interactive=False, elem_classes="output-text") key_output = gr.Textbox(label="Tu Llave Resonante", lines=1, interactive=False) next_to_final_btn = gr.Button("Integrar y Reclamar mi Artefacto") with gr.Column(visible=False) as step4_ui: gr.Markdown("

INTEGRACIÓN Y RESONANCIA

", elem_id="step-title") gr.Markdown("

La obra está completa. El antiguo Eco es ahora un Artefacto de poder. Escucha la nueva resonancia de tu ser. Descarga tu verdad.

", elem_id="step-description") gr.Audio(value=OUTRO_AUDIO, label="Resonancia Alfa (Para Conciencia Integrada)", autoplay=True) artifact_output = gr.Image(label="Tu Artefacto del Alma", interactive=False) download_button = gr.DownloadButton(label="Descargar mi Artefacto del Alma") # --- LÓGICA DE FLUJO AVANZADA --- def s1_to_s2(): return {step1_ui: gr.update(visible=False), step2_ui: gr.update(visible=True)} next_to_step2_btn.click(s1_to_s2, outputs=[step1_ui, step2_ui]) voice_input.change(transcribe_voice, inputs=voice_input, outputs=text_input) def s2_to_s3_flow(user_text): yield {step2_ui: gr.update(visible=False), quantum_tunnel_ui: gr.update(visible=True)} oracle_response = query_oracle(user_text) title = oracle_response.get("title", "Sin Título") myth = oracle_response.get("myth", "Contenido no generado.") key = oracle_response.get("key", "Sin llave.") sigil_img = generate_bioresonant_sigil(user_text) yield { quantum_tunnel_ui: gr.update(visible=False), step3_ui: gr.update(visible=True), myth_title_output: gr.update(value=f"### {title}"), sigil_output: gr.update(value=sigil_img), myth_output: gr.update(value=myth), key_output: gr.update(value=key), } next_to_tunnel_btn.click(s2_to_s3_flow, inputs=text_input, outputs=[step2_ui, quantum_tunnel_ui, step3_ui, myth_title_output, sigil_output, myth_output, key_output]) def s3_to_s4(sigil, title, key): title_clean = title.replace("### ", "") artifact_path = create_soul_artifact(sigil, title_clean, key) return { step3_ui: gr.update(visible=False), step4_ui: gr.update(visible=True), app_container: gr.update(elem_classes="gradio-container final-state"), artifact_output: gr.update(value=artifact_path), download_button: gr.update(value=artifact_path) } next_to_final_btn.click(s3_to_s4, inputs=[sigil_output, myth_title_output, key_output], outputs=[step3_ui, step4_ui, app_container, artifact_output, download_button]) app.launch(debug=True)