JeCabrera commited on
Commit
299bb98
·
verified ·
1 Parent(s): 71e4038

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -172
app.py CHANGED
@@ -69,35 +69,29 @@ EL EQUIPO DE EXPERTOS:
69
 
70
  # Mensaje de bienvenida mejorado
71
  WELCOME_MESSAGE = """
72
- # 🚀 ¡Bienvenido a RoboCopy PUV Creator! 🚀
73
 
74
- Somos un equipo de expertos en marketing y psicología de audiencia, especializados en crear **Propuestas Únicas de Valor (PUVs)** que transforman visitantes en clientes.
75
 
76
- ## 💼 ¿Qué podemos hacer por ti?
77
 
78
- Creamos PUVs poderosas y persuasivas que:
79
  - **Capturan la atención** de tu audiencia ideal
80
- - **Comunican claramente** el valor único de tu oferta
81
  - **Convierten visitantes** en clientes leales
82
 
83
- ## 📋 Para ayudarte, necesitamos conocer:
84
-
85
- 1️⃣ **Tu producto o servicio**: ¿Qué ofreces exactamente? Cuéntanos sus características principales.
86
-
87
- 2️⃣ **Tu audiencia objetivo**: ¿Quiénes son tus clientes ideales? Sé lo más específico posible.
88
 
 
 
89
  3️⃣ **La fórmula que prefieres**:
90
- - **A) Problema-Solución**: "Para [audiencia] que sufre [problema], [producto] proporciona [solución]"
91
- - **B) Antes-Después**: "Transforma [situación actual] en [situación deseada] con [producto]"
92
- - **C) Beneficio Principal**: "[Producto] te ayuda a [beneficio principal] sin [obstáculo común]"
93
-
94
- ## 🔍 Nuestro proceso:
95
 
96
- 1. Analizaremos los puntos de dolor de tu audiencia
97
- 2. Identificaremos los beneficios clave de tu producto/servicio
98
- 3. Crearemos TRES propuestas únicas de valor potentes y persuasivas
99
 
100
- **¡Comencemos!** Por favor, comparte los detalles de tu producto/servicio, audiencia objetivo y la fórmula que prefieres.
101
  """
102
 
103
  # Create a data/ folder if it doesn't already exist
@@ -147,31 +141,14 @@ with st.sidebar:
147
 
148
  st.write('# Creador de Propuestas Únicas de Valor')
149
 
150
- # Inicializar mensajes si es un chat nuevo
151
  if not st.session_state.get('messages'):
152
  st.session_state.messages = []
153
- # Eliminamos el mensaje automático de bienvenida
154
- # No añadimos ningún mensaje inicial
155
- with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
156
- st.markdown(WELCOME_MESSAGE)
157
-
158
- # Guardamos en el historial
159
- st.session_state.messages.append(
160
- dict(
161
- role=MODEL_ROLE,
162
- content=WELCOME_MESSAGE,
163
- avatar=AI_AVATAR_ICON,
164
- )
165
- )
166
 
167
- # Chat history (allows to ask multiple questions)
168
  try:
169
- st.session_state.messages = joblib.load(
170
- f'data/{st.session_state.chat_id}-st_messages'
171
- )
172
- st.session_state.gemini_history = joblib.load(
173
- f'data/{st.session_state.chat_id}-gemini_messages'
174
- )
175
  print('old cache')
176
  except:
177
  if not st.session_state.get('messages'):
@@ -179,152 +156,141 @@ except:
179
  st.session_state.gemini_history = []
180
  print('new_cache made')
181
 
182
- # Configuración del modelo sin el parámetro system_instruction
183
- model = genai.GenerativeModel(
184
- model_name='gemini-2.0-flash'
185
- )
186
  st.session_state.model = model
187
- st.session_state.chat = st.session_state.model.start_chat(
188
- history=st.session_state.gemini_history,
189
- )
190
 
191
  # Si es un chat nuevo, enviar el prompt del sistema como primer mensaje
192
  if not st.session_state.gemini_history:
193
  # Enviamos el prompt del sistema como primer mensaje (invisible para el usuario)
194
  st.session_state.chat.send_message(SYSTEM_PROMPT)
195
- # No guardamos este mensaje en st.session_state.messages para que no se muestre al usuario
196
- # pero sí en gemini_history para que el modelo lo recuerde
197
  st.session_state.gemini_history = st.session_state.chat.history
198
- # Display chat messages from history on app rerun
199
- for message in st.session_state.messages:
200
- with st.chat_message(
201
- name=message['role'],
202
- avatar=message.get('avatar'),
203
- ):
204
- st.markdown(message['content'])
205
 
206
  # React to user input
207
- if prompt := st.chat_input('¿Cuál es tu producto o servicio?'): # Mensaje más específico
208
- # Verificar si es la primera interacción y el usuario pregunta por las funciones
209
- is_asking_about_functions = any(keyword in prompt.lower() for keyword in
210
- ["qué haces", "funciones", "ayudar", "puedes hacer", "cómo funciona", "para qué sirves"])
211
 
212
- if is_asking_about_functions and not past_chats.get(st.session_state.chat_id):
213
- # Si pregunta por las funciones, mostrar el mensaje de bienvenida
214
- response_content = WELCOME_MESSAGE
 
 
215
 
216
- # Display assistant response in chat message container
217
- with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
218
- st.markdown(response_content)
219
-
220
- # Add to chat history
221
- st.session_state.messages.append(
222
- dict(
223
- role=MODEL_ROLE,
224
- content=response_content,
225
- avatar=AI_AVATAR_ICON,
226
- )
227
- )
 
 
 
 
228
  else:
229
- # Procesamiento normal para otras preguntas
230
- # Save this as a chat for later
231
- if st.session_state.chat_id not in past_chats.keys():
232
- # Es una nueva conversación, usamos un título fijo
233
- st.session_state.chat_title = f"PUV Session {time.strftime('%d/%m/%Y')}"
234
- past_chats[st.session_state.chat_id] = st.session_state.chat_title
235
- else:
236
- # Ya existe esta conversación, usamos el título guardado
237
- st.session_state.chat_title = past_chats[st.session_state.chat_id]
238
-
239
- joblib.dump(past_chats, 'data/past_chats_list')
 
 
 
 
 
 
 
 
240
 
241
- # Display user message in chat message container
242
- with st.chat_message('user', avatar=USER_AVATAR_ICON):
243
- st.markdown(prompt)
244
- # Add user message to chat history
245
- st.session_state.messages.append(
246
- dict(
247
- role='user',
248
- content=prompt,
249
- )
250
- )
251
 
252
- # Implementación de reintentos con retroceso exponencial
253
- max_retries = 3
254
- retry_count = 0
255
- while retry_count < max_retries:
256
- try:
257
- ## Send message to AI
258
- response = st.session_state.chat.send_message(
259
- prompt,
260
- stream=True,
261
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
 
263
- # Display assistant response in chat message container
264
- with st.chat_message(
265
- name=MODEL_ROLE,
266
- avatar=AI_AVATAR_ICON,
267
- ):
268
- message_placeholder = st.empty()
269
- full_response = ''
270
- assistant_response = response
271
-
272
- # Añade un indicador de "escribiendo..."
273
- typing_indicator = st.empty()
274
- typing_indicator.markdown("*Nuestro equipo de expertos está analizando tu información...*")
275
-
276
- # Streams in a chunk at a time
277
- for chunk in response:
278
- # Simulate stream of chunk
279
- for ch in chunk.text.split(' '):
280
- full_response += ch + ' '
281
- time.sleep(0.1)
282
- # Rewrites with a cursor at end
283
- message_placeholder.write(full_response + '▌')
284
- # Elimina el indicador de escritura
285
- typing_indicator.empty()
286
- # Write full message with placeholder
287
- message_placeholder.write(full_response)
 
 
288
 
289
- # Add assistant response to chat history
290
- st.session_state.messages.append(
291
- dict(
292
- role=MODEL_ROLE,
293
- content=st.session_state.chat.history[-1].parts[0].text,
294
- avatar=AI_AVATAR_ICON,
295
- )
296
- )
297
- st.session_state.gemini_history = st.session_state.chat.history
298
- # Save to file
299
- joblib.dump(
300
- st.session_state.messages,
301
- f'data/{st.session_state.chat_id}-st_messages',
302
- )
303
- joblib.dump(
304
- st.session_state.gemini_history,
305
- f'data/{st.session_state.chat_id}-gemini_messages',
306
- )
307
- # Si llegamos aquí, la solicitud fue exitosa
308
- break
309
 
310
- except Exception as e:
311
- retry_count += 1
312
- if retry_count >= max_retries:
313
- # Si agotamos los reintentos, mostramos un mensaje de error
314
- with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
315
- st.error(f"Lo sentimos, estamos experimentando problemas para procesar tu solicitud. Por favor, intenta de nuevo más tarde. Error: {str(e)}")
316
- st.session_state.messages.append(
317
- dict(
318
- role=MODEL_ROLE,
319
- content=f"Lo sentimos, estamos experimentando problemas para procesar tu solicitud. Por favor, intenta de nuevo más tarde. Error: {str(e)}",
320
- avatar=AI_AVATAR_ICON,
321
- )
322
- )
323
- joblib.dump(
324
- st.session_state.messages,
325
- f'data/{st.session_state.chat_id}-st_messages',
326
- )
327
- else:
328
- # Esperamos antes de reintentar (retroceso exponencial)
329
- wait_time = (2 ** retry_count) + (time.time() % 1)
330
- time.sleep(wait_time)
 
69
 
70
  # Mensaje de bienvenida mejorado
71
  WELCOME_MESSAGE = """
72
+ # 🚀 ¡Bienvenido! Soy RoboCopy, tu creador de PUVs 🚀
73
 
74
+ Soy un experto en crear **Propuestas Únicas de Valor (PUVs)** que transforman visitantes en clientes.
75
 
76
+ ## 💼 ¿Qué puedo hacer por ti?
77
 
78
+ Creo PUVs persuasivas que:
79
  - **Capturan la atención** de tu audiencia ideal
80
+ - **Comunican claramente** el valor de tu oferta
81
  - **Convierten visitantes** en clientes leales
82
 
83
+ ## 📋 Para ayudarte, necesito conocer:
 
 
 
 
84
 
85
+ 1️⃣ **Tu producto o servicio**: ¿Qué ofreces exactamente?
86
+ 2️⃣ **Tu audiencia objetivo**: ¿Quiénes son tus clientes ideales?
87
  3️⃣ **La fórmula que prefieres**:
88
+ - **A) Problema-Solución**: "Para [audiencia] con [problema], [producto] proporciona [solución]"
89
+ - **B) Antes-Después**: "Transforma [situación actual] en [situación deseada]"
90
+ - **C) Beneficio Principal**: "[Producto] te ayuda a [beneficio] sin [obstáculo]"
 
 
91
 
92
+ Analizaré tu audiencia, identificaré los beneficios clave y crearé TRES propuestas de valor potentes.
 
 
93
 
94
+ **¡Comencemos!** Comparte los detalles de tu producto/servicio, audiencia y fórmula preferida.
95
  """
96
 
97
  # Create a data/ folder if it doesn't already exist
 
141
 
142
  st.write('# Creador de Propuestas Únicas de Valor')
143
 
144
+ # Inicializar mensajes y cargar historial
145
  if not st.session_state.get('messages'):
146
  st.session_state.messages = []
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
+ # Cargar historial de chat si existe
149
  try:
150
+ st.session_state.messages = joblib.load(f'data/{st.session_state.chat_id}-st_messages')
151
+ st.session_state.gemini_history = joblib.load(f'data/{st.session_state.chat_id}-gemini_messages')
 
 
 
 
152
  print('old cache')
153
  except:
154
  if not st.session_state.get('messages'):
 
156
  st.session_state.gemini_history = []
157
  print('new_cache made')
158
 
159
+ # Configuración del modelo
160
+ model = genai.GenerativeModel(model_name='gemini-2.0-flash')
 
 
161
  st.session_state.model = model
162
+ st.session_state.chat = st.session_state.model.start_chat(history=st.session_state.gemini_history)
 
 
163
 
164
  # Si es un chat nuevo, enviar el prompt del sistema como primer mensaje
165
  if not st.session_state.gemini_history:
166
  # Enviamos el prompt del sistema como primer mensaje (invisible para el usuario)
167
  st.session_state.chat.send_message(SYSTEM_PROMPT)
 
 
168
  st.session_state.gemini_history = st.session_state.chat.history
169
+
170
+ # Mostrar mensajes del historial
171
+ for message in st.session_state.messages:
172
+ with st.chat_message(name=message['role'], avatar=message.get('avatar')):
173
+ st.markdown(message['content'])
 
 
174
 
175
  # React to user input
176
+ if prompt := st.chat_input('¿En qué puedo ayudarte hoy?'):
177
+ # Verificar si es el primer mensaje del usuario
178
+ is_first_message = len(st.session_state.messages) == 0
 
179
 
180
+ # Guardar información del chat
181
+ if st.session_state.chat_id not in past_chats.keys():
182
+ # Es una nueva conversación, generamos un título basado en el primer mensaje
183
+ temp_title = f'SesiónChat-{st.session_state.chat_id}'
184
+ past_chats[st.session_state.chat_id] = temp_title
185
 
186
+ # Generamos un título basado en el contenido del mensaje
187
+ try:
188
+ title_generator = genai.GenerativeModel('gemini-2.0-flash')
189
+ title_response = title_generator.generate_content(
190
+ f"Genera un título corto (máximo 5 palabras) que describa de qué trata esta consulta, sin usar comillas ni puntuación: '{prompt}'")
191
+
192
+ generated_title = title_response.text.strip()
193
+
194
+ if generated_title:
195
+ st.session_state.chat_title = generated_title
196
+ past_chats[st.session_state.chat_id] = generated_title
197
+ else:
198
+ st.session_state.chat_title = temp_title
199
+ except Exception as e:
200
+ print(f"Error al generar título: {e}")
201
+ st.session_state.chat_title = temp_title
202
  else:
203
+ # Ya existe esta conversación, usamos el título guardado
204
+ st.session_state.chat_title = past_chats[st.session_state.chat_id]
205
+
206
+ joblib.dump(past_chats, 'data/past_chats_list')
207
+
208
+ # Mostrar mensaje del usuario
209
+ with st.chat_message('user', avatar=USER_AVATAR_ICON):
210
+ st.markdown(prompt)
211
+
212
+ # Añadir mensaje del usuario al historial
213
+ st.session_state.messages.append({
214
+ 'role': 'user',
215
+ 'content': prompt,
216
+ })
217
+
218
+ # Si es el primer mensaje, mostrar el mensaje de bienvenida
219
+ if is_first_message:
220
+ with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
221
+ st.markdown(WELCOME_MESSAGE)
222
 
223
+ st.session_state.messages.append({
224
+ 'role': MODEL_ROLE,
225
+ 'content': WELCOME_MESSAGE,
226
+ 'avatar': AI_AVATAR_ICON,
227
+ })
 
 
 
 
 
228
 
229
+ # Guardar el historial actualizado
230
+ joblib.dump(st.session_state.messages, f'data/{st.session_state.chat_id}-st_messages')
231
+ # Salir de la función para no procesar más este mensaje
232
+ st.experimental_rerun()
233
+
234
+ # Implementación de reintentos con retroceso exponencial
235
+ max_retries = 3
236
+ retry_count = 0
237
+ while retry_count < max_retries:
238
+ try:
239
+ # Enviar mensaje al modelo
240
+ response = st.session_state.chat.send_message(prompt, stream=True)
241
+
242
+ # Mostrar respuesta del asistente
243
+ with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
244
+ message_placeholder = st.empty()
245
+ full_response = ''
246
+
247
+ # Indicador de escritura
248
+ typing_indicator = st.empty()
249
+ typing_indicator.markdown("*Estoy analizando tu información...*")
250
+
251
+ # Mostrar respuesta por fragmentos
252
+ for chunk in response:
253
+ for ch in chunk.text.split(' '):
254
+ full_response += ch + ' '
255
+ time.sleep(0.1)
256
+ message_placeholder.write(full_response + '▌')
257
 
258
+ # Eliminar indicador y mostrar respuesta completa
259
+ typing_indicator.empty()
260
+ message_placeholder.write(full_response)
261
+
262
+ # Añadir respuesta al historial
263
+ st.session_state.messages.append({
264
+ 'role': MODEL_ROLE,
265
+ 'content': st.session_state.chat.history[-1].parts[0].text,
266
+ 'avatar': AI_AVATAR_ICON,
267
+ })
268
+
269
+ # Actualizar historial
270
+ st.session_state.gemini_history = st.session_state.chat.history
271
+
272
+ # Guardar historial
273
+ joblib.dump(st.session_state.messages, f'data/{st.session_state.chat_id}-st_messages')
274
+ joblib.dump(st.session_state.gemini_history, f'data/{st.session_state.chat_id}-gemini_messages')
275
+
276
+ # Salir del bucle si la solicitud fue exitosa
277
+ break
278
+
279
+ except Exception as e:
280
+ retry_count += 1
281
+ if retry_count >= max_retries:
282
+ # Mostrar mensaje de error si se agotan los reintentos
283
+ with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
284
+ st.error(f"Lo siento, estoy experimentando problemas para procesar tu solicitud. Por favor, intenta de nuevo más tarde. Error: {str(e)}")
285
 
286
+ st.session_state.messages.append({
287
+ 'role': MODEL_ROLE,
288
+ 'content': f"Lo siento, estoy experimentando problemas para procesar tu solicitud. Por favor, intenta de nuevo más tarde. Error: {str(e)}",
289
+ 'avatar': AI_AVATAR_ICON,
290
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
+ joblib.dump(st.session_state.messages, f'data/{st.session_state.chat_id}-st_messages')
293
+ else:
294
+ # Esperar antes de reintentar (retroceso exponencial)
295
+ wait_time = (2 ** retry_count) + (time.time() % 1)
296
+ time.sleep(wait_time)