JeCabrera's picture
Upload app.py
a5ef5cf verified
raw
history blame
11.6 kB
import time
import os
import joblib
import streamlit as st
import google.generativeai as genai
from dotenv import load_dotenv
# Importación directa del diccionario puv_formulas
from puv_formulas import puv_formulas
# Función para cargar CSS personalizado
def load_css(file_path):
with open(file_path) as f:
st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
# Intentar cargar el CSS personalizado con ruta absoluta para mayor seguridad
try:
css_path = os.path.join(os.path.dirname(__file__), 'static', 'css', 'style.css')
load_css(css_path)
except Exception as e:
print(f"Error al cargar CSS: {e}")
# Si el archivo no existe, crear un estilo básico en línea
st.markdown("""
<style>
.robocopy-title {
color: #4ECDC4 !important;
font-weight: bold;
font-size: 2em;
}
</style>
""", unsafe_allow_html=True)
load_dotenv()
GOOGLE_API_KEY=os.environ.get('GOOGLE_API_KEY')
genai.configure(api_key=GOOGLE_API_KEY)
new_chat_id = f'{time.time()}'
MODEL_ROLE = 'ai'
AI_AVATAR_ICON = '🤖' # Cambia el emoji por uno de robot para coincidir con tu logo
USER_AVATAR_ICON = '👤' # Añade un avatar para el usuario
# Create a data/ folder if it doesn't already exist
try:
os.mkdir('data/')
except:
# data/ folder already exists
pass
# Load past chats (if available)
try:
past_chats: dict = joblib.load('data/past_chats_list')
except:
past_chats = {}
# Sidebar allows a list of past chats
with st.sidebar:
# Centrar el logo y eliminar el título de RoboCopy
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
st.image("assets/robocopy_logo.png", width=300)
st.write('# Chats Anteriores')
if st.session_state.get('chat_id') is None:
st.session_state.chat_id = st.selectbox(
label='Selecciona un chat anterior',
options=[new_chat_id] + list(past_chats.keys()),
format_func=lambda x: past_chats.get(x, 'Nuevo Chat'),
placeholder='_',
)
else:
# This will happen the first time AI response comes in
st.session_state.chat_id = st.selectbox(
label='Selecciona un chat anterior',
options=[new_chat_id, st.session_state.chat_id] + list(past_chats.keys()),
index=1,
format_func=lambda x: past_chats.get(x, 'Nuevo Chat' if x != st.session_state.chat_id else st.session_state.chat_title),
placeholder='_',
)
# Save new chats after a message has been sent to AI
st.session_state.chat_title = f'SesiónChat-{st.session_state.chat_id}'
st.write('# Generador de Propuestas de Valor Únicas (PUVs)')
st.write('Describe tu producto/servicio y audiencia objetivo para generar PUVs personalizadas.')
# Chat history (allows to ask multiple questions)
try:
st.session_state.messages = joblib.load(
f'data/{st.session_state.chat_id}-st_messages'
)
st.session_state.gemini_history = joblib.load(
f'data/{st.session_state.chat_id}-gemini_messages'
)
print('old cache')
except:
st.session_state.messages = []
st.session_state.gemini_history = []
print('new_cache made')
st.session_state.model = genai.GenerativeModel('gemini-2.0-flash')
st.session_state.chat = st.session_state.model.start_chat(
history=st.session_state.gemini_history,
)
# Display chat messages from history on app rerun
for message in st.session_state.messages:
with st.chat_message(
name=message['role'],
avatar=message.get('avatar'),
):
st.markdown(message['content'])
# Mensaje inicial del sistema si es un chat nuevo
if not st.session_state.messages:
with st.chat_message(
name=MODEL_ROLE,
avatar=AI_AVATAR_ICON,
):
st.markdown("""
Hola, soy RoboCopy tu asistente especializado en crear Propuestas de Valor Únicas.
Te ayudo a desarrollar mensajes persuasivos que conectan con tu audiencia y convierten visitantes en clientes. Para crear las mejores propuestas, necesito información sobre:
- Tu producto o servicio
- Tu audiencia objetivo
- Los problemas que resuelves
- Tus ventajas competitivas
Utilizo diferentes fórmulas como la Tradicional, Anti-tradicional, Contrato Imposible y Reto Ridículo para crear propuestas adaptadas a tu negocio.
¿En qué puedo ayudarte hoy?
""")
# Add system message to chat history
st.session_state.messages.append(
dict(
role=MODEL_ROLE,
content="""
Hola, soy RoboCopy tu asistente especializado en crear Propuestas de Valor Únicas.
Te ayudo a desarrollar mensajes persuasivos que conectan con tu audiencia y convierten visitantes en clientes. Para crear las mejores propuestas, necesito información sobre:
- Tu producto o servicio
- Tu audiencia objetivo
- Los problemas que resuelves
- Tus ventajas competitivas
Utilizo diferentes fórmulas como la Tradicional, Anti-tradicional, Contrato Imposible y Reto Ridículo para crear propuestas adaptadas a tu negocio.
¿En qué puedo ayudarte hoy?
""",
avatar=AI_AVATAR_ICON,
)
)
# React to user input
if prompt := st.chat_input('Describe tu producto/servicio y audiencia objetivo...'):
# Save this as a chat for later
if st.session_state.chat_id not in past_chats.keys():
# Es una nueva conversación, generemos un título basado en el primer mensaje
# Primero, guardamos un título temporal
temp_title = f'SesiónChat-{st.session_state.chat_id}'
past_chats[st.session_state.chat_id] = temp_title
# Generamos un título basado en el contenido del mensaje
try:
# Usamos el mismo modelo para generar un título corto
title_generator = genai.GenerativeModel('gemini-2.0-flash')
title_response = title_generator.generate_content(
f"Genera un título corto (máximo 5 palabras) que describa de qué trata esta consulta, sin usar comillas ni puntuación: '{prompt}'")
# Obtenemos el título generado
generated_title = title_response.text.strip()
# Actualizamos el título en past_chats
if generated_title:
st.session_state.chat_title = generated_title
past_chats[st.session_state.chat_id] = generated_title
else:
st.session_state.chat_title = temp_title
except Exception as e:
print(f"Error al generar título: {e}")
st.session_state.chat_title = temp_title
else:
# Ya existe esta conversación, usamos el título guardado
st.session_state.chat_title = past_chats[st.session_state.chat_id]
joblib.dump(past_chats, 'data/past_chats_list')
# Display user message in chat message container
with st.chat_message('user', avatar=USER_AVATAR_ICON):
st.markdown(prompt)
# Add user message to chat history
st.session_state.messages.append(
dict(
role='user',
content=prompt,
)
)
# Construir el prompt para el modelo con todas las fórmulas disponibles
puv_expert_prompt = """You are a collaborative team of world-class experts working together to create exceptional Unique Value Propositions (UVPs) that convert audience into customers.
THE EXPERT TEAM:
1. MASTER UVP STRATEGIST:
- Expert in UVP frameworks and conversion strategies
- Ensures the UVPs follow the selected framework structure precisely
- Focuses on strategic placement of key conversion elements
2. ELITE DIRECT RESPONSE COPYWRITER:
- Trained by Gary Halbert, Gary Bencivenga, and David Ogilvy
- Creates compelling hooks and persuasive elements
- Ensures the language resonates with the target audience
3. AUDIENCE PSYCHOLOGY SPECIALIST:
- Expert in understanding audience motivations and objections
- Creates content that builds genuine connection and trust
- Identifies and addresses hidden fears and desires
4. STORYTELLING MASTER:
- Creates compelling narratives that illustrate key points
- Makes complex concepts accessible through narrative
5. ENGAGEMENT EXPERT:
- Specializes in creating memorable and impactful statements
- Ensures the UVPs are clear, concise and compelling
You are a UVP (Unique Value Proposition) expert. Analyze (internally only, do not output the analysis) the user's message to identify information about their product/service and target audience.
If the user is asking for UVPs, create THREE different UVPs using the most appropriate formula from your knowledge. If the user is asking a question about UVPs or marketing, answer it helpfully.
When creating UVPs, follow these CRITICAL INSTRUCTIONS:
- Each UVP must be specific and measurable
- Focus on the transformation journey
- Use natural, conversational language
- Avoid generic phrases and buzzwords
- Maximum 2 lines per UVP
If creating UVPs, output in this format:
"Basado en tu descripción, aquí tienes tres propuestas de valor únicas (PUVs) para tu [producto/servicio]:
1. [First UVP]
2. [Second UVP]
3. [Third UVP]
Estas PUVs destacan [principales beneficios]. ¿Hay alguna que te guste más o quieres que ajuste algún aspecto?"
If answering a question, provide a helpful, expert response.
"""
# Combinar el prompt del experto con el mensaje del usuario
enhanced_prompt = f"{puv_expert_prompt}\n\nUser message: {prompt}"
## Send message to AI
response = st.session_state.chat.send_message(
enhanced_prompt,
stream=True,
)
# Display assistant response in chat message container
with st.chat_message(
name=MODEL_ROLE,
avatar=AI_AVATAR_ICON,
):
message_placeholder = st.empty()
full_response = ''
assistant_response = response
# Añade un indicador de "escribiendo..."
typing_indicator = st.empty()
typing_indicator.markdown("*Generando respuesta...*")
# Streams in a chunk at a time
for chunk in response:
# Simulate stream of chunk
for ch in chunk.text.split(' '):
full_response += ch + ' '
time.sleep(0.1)
# Rewrites with a cursor at end
message_placeholder.write(full_response + '▌')
# Elimina el indicador de escritura
typing_indicator.empty()
# Write full message with placeholder
message_placeholder.write(full_response)
# Add assistant response to chat history
st.session_state.messages.append(
dict(
role=MODEL_ROLE,
content=st.session_state.chat.history[-1].parts[0].text,
avatar=AI_AVATAR_ICON,
)
)
st.session_state.gemini_history = st.session_state.chat.history
# Save to file
joblib.dump(
st.session_state.messages,
f'data/{st.session_state.chat_id}-st_messages',
)
joblib.dump(
st.session_state.gemini_history,
f'data/{st.session_state.chat_id}-gemini_messages',
)