from dotenv import load_dotenv import streamlit as st import os import google.generativeai as genai from style import styles from prompts import create_instruction from consciousness_levels import CONSCIOUSNESS_LEVELS # Cargar las variables de entorno load_dotenv() # Configurar la API de Google genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) # Inicializar variables de estado en session_state si no existen if 'perfil_cliente' not in st.session_state: st.session_state.perfil_cliente = None if 'producto' not in st.session_state: st.session_state.producto = "" if 'habilidades' not in st.session_state: st.session_state.habilidades = "" if 'creatividad' not in st.session_state: st.session_state.creatividad = 1.0 if 'nivel_conciencia' not in st.session_state: st.session_state.nivel_conciencia = "Ninguno" # Función para generar el perfil de cliente ideal @st.cache_resource def get_model(temperature): generation_config = { "temperature": temperature, } return genai.GenerativeModel('gemini-2.0-flash', generation_config=generation_config) def generate_buyer_persona(product, skills, target_audience, temperature, consciousness_level="Ninguno"): if not product or not skills: return "Por favor, completa los campos de producto y habilidades." try: model = get_model(temperature) instruction = create_instruction( product_service=product, skills=skills, target_audience=target_audience, consciousness_level=consciousness_level ) # Añadir instrucción explícita para respuesta en español instruction += "\n\nIMPORTANTE: La respuesta debe estar completamente en español." response = model.generate_content([instruction], generation_config={"temperature": temperature}) return response.parts[0].text if response and response.parts else "Error generando el perfil de cliente ideal." except Exception as e: return f"Error al generar el perfil: {str(e)}" # Modificar la función update_profile para que no use spinner def update_profile(): # Solo actualizar la variable de sesión st.session_state.submitted = True # Configurar la interfaz de usuario con Streamlit st.set_page_config(page_title="Generador de Cliente Ideal", page_icon="👤", layout="wide") # Leer el contenido del archivo manual.md si existe try: with open("manual.md", "r", encoding="utf-8") as file: manual_content = file.read() # Mostrar el contenido del manual en el sidebar st.sidebar.markdown(manual_content) except FileNotFoundError: st.sidebar.warning("Manual not found. Please create a manual.md file.") except Exception as e: st.sidebar.error(f"Error loading manual: {str(e)}") # Ocultar elementos de la interfaz st.markdown(styles["main_layout"], unsafe_allow_html=True) # Centrar el título y el subtítulo st.markdown("

Generador de Perfil de Cliente Ideal

", unsafe_allow_html=True) st.markdown("

Crea un perfil detallado de tu cliente ideal basado en tu producto y habilidades.

", unsafe_allow_html=True) # Añadir CSS personalizado para el botón st.markdown(styles["button"], unsafe_allow_html=True) # Añadir CSS personalizado para el botón de descarga st.markdown(styles["download_button"], unsafe_allow_html=True) # Crear columnas col1, col2 = st.columns([1, 2]) # Columna de entrada with col1: producto = st.text_area("¿Qué producto o servicio ofreces?", value=st.session_state.producto, placeholder="Ejemplo: Curso de Inglés", key="producto_input", height=70) st.session_state.producto = producto habilidades = st.text_area("¿Cuáles son tus habilidades principales?", value=st.session_state.habilidades, placeholder="Ejemplo: Enseñanza, comunicación, diseño de contenidos", key="habilidades_input", height=70) st.session_state.habilidades = habilidades # Crear un acordeón para las opciones de personalización with st.expander("Personaliza Tu Cliente Ideal Soñado"): # Nuevo campo para público objetivo if 'publico_objetivo' not in st.session_state: st.session_state.publico_objetivo = "" publico_objetivo = st.text_area("¿Cuál es tu público objetivo? (opcional)", value=st.session_state.publico_objetivo, placeholder="Ejemplo: Profesionales entre 25-40 años interesados en desarrollo personal", key="publico_objetivo_input", height=70) st.session_state.publico_objetivo = publico_objetivo # Nivel de creatividad con slider creatividad = st.slider("Nivel de creatividad", min_value=0.0, max_value=2.0, value=st.session_state.creatividad, step=0.1, key="creatividad_slider") st.session_state.creatividad = creatividad # Selector de nivel de conciencia # Create a list with "Ninguno" and the numbered consciousness levels consciousness_options = ["Ninguno"] for i, key in enumerate(CONSCIOUSNESS_LEVELS.keys(), 1): # Replace underscores with spaces in the key display_name = key.replace("_", " ") consciousness_options.append(f"Nivel {i} - {display_name}") nivel_conciencia_display = st.selectbox( "Nivel de conciencia del cliente ideal", consciousness_options, index=0, help="Selecciona el nivel de conciencia en el que se encuentra tu cliente ideal" ) # Map back to the original consciousness level name for processing if nivel_conciencia_display == "Ninguno": nivel_conciencia = "Ninguno" else: # Extract the original key from the display name level_number = nivel_conciencia_display.split(" - ")[0].replace("Nivel ", "") original_key = list(CONSCIOUSNESS_LEVELS.keys())[int(level_number) - 1] nivel_conciencia = original_key.replace("_", " ") st.session_state.nivel_conciencia = nivel_conciencia if nivel_conciencia != "Ninguno": # Get the description from the CONSCIOUSNESS_LEVELS dictionary original_key = nivel_conciencia.replace(" ", "_") if original_key in CONSCIOUSNESS_LEVELS: nivel_info = CONSCIOUSNESS_LEVELS[original_key]["estado_mental"] st.info(f"**{nivel_conciencia}**: {nivel_info}") # Botón para generar submit = st.button("GENERAR PERFIL DE CLIENTE IDEAL", on_click=update_profile) # Columna de resultados with col2: # Verificar si se ha enviado el formulario if 'submitted' in st.session_state and st.session_state.submitted: if st.session_state.producto and st.session_state.habilidades: with st.spinner("Creando tu Cliente Ideal Soñado..."): # Generar el perfil del cliente perfil_cliente = generate_buyer_persona( st.session_state.producto, st.session_state.habilidades, st.session_state.publico_objetivo, st.session_state.creatividad, st.session_state.nivel_conciencia ) # Guardar en session_state st.session_state.perfil_cliente = perfil_cliente # Resetear el estado de envío st.session_state.submitted = False # Mostrar resultados if not isinstance(st.session_state.perfil_cliente, str): st.error("Error al generar el perfil de cliente ideal") else: # Crear un contenedor con estilo personalizado st.markdown(f""" """, unsafe_allow_html=True) # Usar un expander sin título para contener todo el resultado with st.expander("", expanded=True): st.markdown("

Tu Cliente Ideal

", unsafe_allow_html=True) st.markdown(st.session_state.perfil_cliente) # Opción para descargar st.download_button( label="Descargar Perfil", data=st.session_state.perfil_cliente, file_name="cliente_ideal.txt", mime="text/plain" ) else: st.warning("Por favor, completa los campos de producto y habilidades antes de generar el perfil.") # Mostrar resultados anteriores si existen elif st.session_state.perfil_cliente: # Crear un contenedor con estilo personalizado st.markdown(f""" """, unsafe_allow_html=True) # Usar un expander sin título para contener todo el resultado with st.expander("", expanded=True): st.markdown("

Tu Cliente Ideal

", unsafe_allow_html=True) st.markdown(st.session_state.perfil_cliente) # Opción para descargar st.download_button( label="Descargar Perfil", data=st.session_state.perfil_cliente, file_name="cliente_ideal.txt", mime="text/plain" )