import streamlit as st # Configurar la interfaz de usuario con Streamlit - MUST BE FIRST! st.set_page_config(page_title="Generador de Cliente Ideal", page_icon="馃懁", layout="wide") from dotenv import load_dotenv 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 # Update the default format in session state if 'formato' not in st.session_state: st.session_state.formato = "Jung's_Avatar" # Changed from previous format name if 'nivel_conciencia' not in st.session_state: # Usar el primer nivel del diccionario como valor predeterminado first_key = list(CONSCIOUSNESS_LEVELS.keys())[0] st.session_state.nivel_conciencia = first_key.replace("_", " ") # 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) # Update the format selection dropdown to include the new format name formato = st.selectbox( "Formato del perfil", options=["Jung's_Avatar", "busqueda_format", "story_format", "simple_format"], format_func=lambda x: x.replace("_", " ").title(), help="Selecciona el formato para tu perfil de cliente ideal" ) def generate_buyer_persona(product, skills, target_audience, temperature, consciousness_level="Ninguno", format_type="Jung's_Avatar"): 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, format_type=format_type ) # 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 # 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 # Bot贸n para generar - Movido arriba del acorde贸n submit = st.button("CREAR MI CLIENTE IDEAL SO脩ADO 鉃も灓", on_click=update_profile) # 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 # Selector de formato from format.format import buyer_persona_formats # Obtener directamente las claves que terminan en "_format" del diccionario format_keys = [key for key in buyer_persona_formats.keys() if key.endswith("_format")] formato = st.selectbox( "Formato del perfil", options=format_keys, format_func=lambda x: x.replace("_format", "").capitalize() + " format", index=format_keys.index(st.session_state.formato) if st.session_state.formato in format_keys else 0, help="Selecciona el formato en el que se presentar谩 el perfil del cliente ideal" ) st.session_state.formato = formato # 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 consciousness_options = [] 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" ) # 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("_", " ") # Get the description from the CONSCIOUSNESS_LEVELS dictionary if original_key in CONSCIOUSNESS_LEVELS: nivel_info = CONSCIOUSNESS_LEVELS[original_key]["estado_mental"] st.info(f"**{nivel_conciencia}**: {nivel_info}") st.session_state.nivel_conciencia = nivel_conciencia # 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, st.session_state.formato ) # 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 MI CLIENTE SO脩ADO 鉃も灓", 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 MI CLIENTE SO脩ADO 鉃も灓", data=st.session_state.perfil_cliente, file_name="cliente_ideal.txt", mime="text/plain" )