import streamlit as st import base64 import io import os from openai import OpenAI # ====================================== # CONFIGURACIÓN DE STREAMLIT # ====================================== st.set_page_config( page_title="AIDEN – Voz Latina", page_icon="🎙️", layout="centered" ) # ====================================== # LEER API KEY DESDE ENTORNO (HF Secrets) # ====================================== API_KEY = os.environ.get("OPENAI_API_KEY") if not API_KEY: st.error("❌ ERROR: No se encontró OPENAI_API_KEY en HuggingFace Secrets.") st.stop() client = OpenAI(api_key=API_KEY) # ====================================== # FUNCIONES AUXILIARES # ====================================== def cargar_logo(path): with open(path, "rb") as f: return base64.b64encode(f.read()).decode() logo_b64 = cargar_logo("assets/aiden_logo.png") def sintetizar_voz(texto): """Texto → Voz WAV usando OpenAI.""" reply = client.audio.speech.create( model="gpt-4o-mini-tts", voice="male", format="wav", input=texto ) return reply.read() def transcribir_audio(audio_bytes): """Voz → Texto (Whisper-1).""" transcript = client.audio.transcriptions.create( model="whisper-1", file=("audio.wav", audio_bytes, "audio/wav") ) return transcript.text def generar_respuesta(prompt): """Respuesta estilo AIDEN.""" completion = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": ( "Eres AIDEN, IA de voz profesional creada por JMC Studio Digital " "en Guayaquil por George Márquez. Respondes SIEMPRE en español latino, " "tono humano, muy natural, cálido, profesional." )}, {"role": "user", "content": prompt} ], temperature=0.7, max_tokens=300 ) return completion.choices[0].message.content # ====================================== # INTERFAZ # ====================================== st.markdown( f"""

AIDEN — Conversación por Voz

Habla con AIDEN usando tu micrófono — voz natural, fluida y profesional.

""", unsafe_allow_html=True ) st.write("### 🎙️ Hablar con AIDEN") audio_file = st.file_uploader( "Graba o sube un audio (WAV/MP3)…", type=["wav", "mp3"] ) # Historial (últimos 4 turnos) if "historial" not in st.session_state: st.session_state.historial = [] texto_manual = st.text_input("O escribe tu mensaje (opcional)…") # ====================================== # PROCESAR MENSAJE # ====================================== if st.button("Enviar mensaje a AIDEN"): if audio_file: st.info("🎧 Procesando tu voz…") audio_bytes = audio_file.read() try: texto_usuario = transcribir_audio(audio_bytes) except Exception as e: st.error(f"Error al transcribir audio: {e}") st.stop() st.write("### 🗣️ Lo que dijiste:") st.write(texto_usuario) elif texto_manual.strip(): texto_usuario = texto_manual.strip() st.write("### 🗣️ Mensaje enviado:") st.write(texto_usuario) else: st.warning("Debes subir un audio o escribir texto.") st.stop() # Guardar historial st.session_state.historial.append({"role": "user", "content": texto_usuario}) st.session_state.historial = st.session_state.historial[-4:] # Contexto contexto = "" for msg in st.session_state.historial: if msg["role"] == "user": contexto += f"Usuario: {msg['content']}\n" else: contexto += f"AIDEN: {msg['content']}\n" # Generación try: respuesta = generar_respuesta(contexto) except Exception as e: st.error(f"Error generando respuesta: {e}") st.stop() st.write("### 🤖 Respuesta de AIDEN:") st.write(respuesta) st.session_state.historial.append({"role": "assistant", "content": respuesta}) # TTS st.write("### 🔊 Voz de AIDEN") try: audio_out = sintetizar_voz(respuesta) st.audio(audio_out, format="audio/wav") except Exception as e: st.error(f"Error generando voz: {e}") # Footer st.write("---") st.markdown( "

AIDEN — Desarrollado por JMC Studio Digital

", unsafe_allow_html=True )