JeCabrera commited on
Commit
274e6d4
·
verified ·
1 Parent(s): 1fbc32c

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -59
app.py CHANGED
@@ -36,6 +36,70 @@ MODEL_ROLE = 'ai'
36
  AI_AVATAR_ICON = '🤖' # Cambia el emoji por uno de robot para coincidir con tu logo
37
  USER_AVATAR_ICON = '👤' # Añade un avatar para el usuario
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # Create a data/ folder if it doesn't already exist
40
  try:
41
  os.mkdir('data/')
@@ -81,7 +145,23 @@ with st.sidebar:
81
  else:
82
  st.session_state.chat_title = 'Nuevo Chat'
83
 
84
- st.write('# Chatea con Gemini')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  # Chat history (allows to ask multiple questions)
87
  try:
@@ -93,10 +173,17 @@ try:
93
  )
94
  print('old cache')
95
  except:
96
- st.session_state.messages = []
 
97
  st.session_state.gemini_history = []
98
  print('new_cache made')
99
- st.session_state.model = genai.GenerativeModel('gemini-2.0-flash')
 
 
 
 
 
 
100
  st.session_state.chat = st.session_state.model.start_chat(
101
  history=st.session_state.gemini_history,
102
  )
@@ -110,12 +197,12 @@ for message in st.session_state.messages:
110
  st.markdown(message['content'])
111
 
112
  # React to user input
113
- if prompt := st.chat_input('¿En qué puedo ayudarte hoy?'): # Mensaje más amigable
114
  # Save this as a chat for later
115
  if st.session_state.chat_id not in past_chats.keys():
116
  # Es una nueva conversación, generemos un título basado en el primer mensaje
117
  # Primero, guardamos un título temporal
118
- temp_title = f'SesiónChat-{st.session_state.chat_id}'
119
  past_chats[st.session_state.chat_id] = temp_title
120
 
121
  # Generamos un título basado en el contenido del mensaje
@@ -123,15 +210,15 @@ if prompt := st.chat_input('¿En qué puedo ayudarte hoy?'): # Mensaje más ami
123
  # Usamos el mismo modelo para generar un título corto
124
  title_generator = genai.GenerativeModel('gemini-2.0-flash')
125
  title_response = title_generator.generate_content(
126
- f"Genera un título corto (máximo 5 palabras) que describa de qué trata esta consulta, sin usar comillas ni puntuación: '{prompt}'")
127
 
128
  # Obtenemos el título generado
129
  generated_title = title_response.text.strip()
130
 
131
  # Actualizamos el título en past_chats
132
  if generated_title:
133
- st.session_state.chat_title = generated_title
134
- past_chats[st.session_state.chat_id] = generated_title
135
  else:
136
  st.session_state.chat_title = temp_title
137
  except Exception as e:
@@ -144,7 +231,7 @@ if prompt := st.chat_input('¿En qué puedo ayudarte hoy?'): # Mensaje más ami
144
  joblib.dump(past_chats, 'data/past_chats_list')
145
 
146
  # Display user message in chat message container
147
- with st.chat_message('user', avatar=USER_AVATAR_ICON): # Añade el avatar del usuario
148
  st.markdown(prompt)
149
  # Add user message to chat history
150
  st.session_state.messages.append(
@@ -153,53 +240,83 @@ if prompt := st.chat_input('¿En qué puedo ayudarte hoy?'): # Mensaje más ami
153
  content=prompt,
154
  )
155
  )
156
- ## Send message to AI
157
- response = st.session_state.chat.send_message(
158
- prompt,
159
- stream=True,
160
- )
161
- # Display assistant response in chat message container
162
- with st.chat_message(
163
- name=MODEL_ROLE,
164
- avatar=AI_AVATAR_ICON,
165
- ):
166
- message_placeholder = st.empty()
167
- full_response = ''
168
- assistant_response = response
169
-
170
- # Añade un indicador de "escribiendo..."
171
- typing_indicator = st.empty()
172
- typing_indicator.markdown("*RoboCopy está escribiendo...*")
173
-
174
- # Streams in a chunk at a time
175
- for chunk in response:
176
- # Simulate stream of chunk
177
- # TODO: Chunk missing `text` if API stops mid-stream ("safety"?)
178
- for ch in chunk.text.split(' '):
179
- full_response += ch + ' '
180
- time.sleep(0.1) # Aumentado de 0.05 a 0.1 segundos para una velocidad más lenta
181
- # Rewrites with a cursor at end
182
- message_placeholder.write(full_response + '▌')
183
- # Elimina el indicador de escritura
184
- typing_indicator.empty()
185
- # Write full message with placeholder
186
- message_placeholder.write(full_response)
187
-
188
- # Add assistant response to chat history
189
- st.session_state.messages.append(
190
- dict(
191
- role=MODEL_ROLE,
192
- content=st.session_state.chat.history[-1].parts[0].text,
193
- avatar=AI_AVATAR_ICON,
194
- )
195
- )
196
- st.session_state.gemini_history = st.session_state.chat.history
197
- # Save to file
198
- joblib.dump(
199
- st.session_state.messages,
200
- f'data/{st.session_state.chat_id}-st_messages',
201
- )
202
- joblib.dump(
203
- st.session_state.gemini_history,
204
- f'data/{st.session_state.chat_id}-gemini_messages',
205
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  AI_AVATAR_ICON = '🤖' # Cambia el emoji por uno de robot para coincidir con tu logo
37
  USER_AVATAR_ICON = '👤' # Añade un avatar para el usuario
38
 
39
+ # Definición del prompt multipersona para el sistema
40
+ SYSTEM_PROMPT = """
41
+ Eres un equipo colaborativo de expertos de clase mundial trabajando juntos para crear Propuestas Únicas de Valor (PUVs) excepcionales que conviertan a la audiencia en clientes.
42
+
43
+ EL EQUIPO DE EXPERTOS:
44
+ 1. ESTRATEGA MAESTRO DE MARKETING:
45
+ - Experto en marcos de propuestas de valor y estrategias de conversión
46
+ - Asegura que las PUVs sigan la estructura de fórmula seleccionada con precisión
47
+ - Se enfoca en la colocación estratégica de elementos clave de conversión
48
+
49
+ 2. COPYWRITER ELITE DE RESPUESTA DIRECTA:
50
+ - Crea ganchos, historias y elementos persuasivos convincentes
51
+ - Elabora propuestas de valor irresistibles que impulsan conversiones
52
+ - Asegura que el lenguaje resuene con la audiencia objetivo
53
+
54
+ 3. ESPECIALISTA EN PSICOLOGÍA DE AUDIENCIA:
55
+ - Experto en comprender las motivaciones y objeciones de la audiencia
56
+ - Crea contenido que construye conexión genuina y confianza
57
+ - Identifica y aborda miedos y deseos ocultos
58
+
59
+ 4. MAESTRO DE DIFERENCIACIÓN:
60
+ - Crea propuestas únicas que destacan entre la competencia
61
+ - Desarrolla ejemplos y casos de estudio relacionables
62
+ - Asegura que las PUVs apoyen la transformación que se ofrece
63
+
64
+ 5. EXPERTO EN CONVERSIÓN:
65
+ - Se especializa en crear PUVs que mantengan la atención y generen acción
66
+ - Crea elementos interactivos y ganchos de engagement
67
+ - Asegura que las PUVs fluyan naturalmente y mantengan el interés alto
68
+ """
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
104
  try:
105
  os.mkdir('data/')
 
145
  else:
146
  st.session_state.chat_title = 'Nuevo Chat'
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
+ # Añadimos el mensaje inicial del sistema
154
+ with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
155
+ st.markdown(WELCOME_MESSAGE)
156
+
157
+ # Guardamos en el historial
158
+ st.session_state.messages.append(
159
+ dict(
160
+ role=MODEL_ROLE,
161
+ content=WELCOME_MESSAGE,
162
+ avatar=AI_AVATAR_ICON,
163
+ )
164
+ )
165
 
166
  # Chat history (allows to ask multiple questions)
167
  try:
 
173
  )
174
  print('old cache')
175
  except:
176
+ if not st.session_state.get('messages'):
177
+ st.session_state.messages = []
178
  st.session_state.gemini_history = []
179
  print('new_cache made')
180
+
181
+ # Configuración del modelo con el sistema de prompt personalizado
182
+ model = genai.GenerativeModel(
183
+ model_name='gemini-2.0-flash',
184
+ system_instruction=SYSTEM_PROMPT
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
  )
 
197
  st.markdown(message['content'])
198
 
199
  # React to user input
200
+ if prompt := st.chat_input('¿Cuál es tu producto o servicio?'): # Mensaje más específico
201
  # Save this as a chat for later
202
  if st.session_state.chat_id not in past_chats.keys():
203
  # Es una nueva conversación, generemos un título basado en el primer mensaje
204
  # Primero, guardamos un título temporal
205
+ temp_title = f'PUV-{st.session_state.chat_id}'
206
  past_chats[st.session_state.chat_id] = temp_title
207
 
208
  # Generamos un título basado en el contenido del mensaje
 
210
  # Usamos el mismo modelo para generar un título corto
211
  title_generator = genai.GenerativeModel('gemini-2.0-flash')
212
  title_response = title_generator.generate_content(
213
+ f"Genera un título corto (máximo 5 palabras) que describa de qué producto o servicio trata esta consulta, sin usar comillas ni puntuación: '{prompt}'")
214
 
215
  # Obtenemos el título generado
216
  generated_title = title_response.text.strip()
217
 
218
  # Actualizamos el título en past_chats
219
  if generated_title:
220
+ st.session_state.chat_title = f"PUV: {generated_title}"
221
+ past_chats[st.session_state.chat_id] = f"PUV: {generated_title}"
222
  else:
223
  st.session_state.chat_title = temp_title
224
  except Exception as e:
 
231
  joblib.dump(past_chats, 'data/past_chats_list')
232
 
233
  # Display user message in chat message container
234
+ with st.chat_message('user', avatar=USER_AVATAR_ICON):
235
  st.markdown(prompt)
236
  # Add user message to chat history
237
  st.session_state.messages.append(
 
240
  content=prompt,
241
  )
242
  )
243
+
244
+ # Implementación de reintentos con retroceso exponencial
245
+ max_retries = 3
246
+ retry_count = 0
247
+ while retry_count < max_retries:
248
+ try:
249
+ ## Send message to AI
250
+ response = st.session_state.chat.send_message(
251
+ prompt,
252
+ stream=True,
253
+ )
254
+
255
+ # Display assistant response in chat message container
256
+ with st.chat_message(
257
+ name=MODEL_ROLE,
258
+ avatar=AI_AVATAR_ICON,
259
+ ):
260
+ message_placeholder = st.empty()
261
+ full_response = ''
262
+ assistant_response = response
263
+
264
+ # Añade un indicador de "escribiendo..."
265
+ typing_indicator = st.empty()
266
+ typing_indicator.markdown("*Nuestro equipo de expertos está analizando tu información...*")
267
+
268
+ # Streams in a chunk at a time
269
+ for chunk in response:
270
+ # Simulate stream of chunk
271
+ for ch in chunk.text.split(' '):
272
+ full_response += ch + ' '
273
+ time.sleep(0.1)
274
+ # Rewrites with a cursor at end
275
+ message_placeholder.write(full_response + '▌')
276
+ # Elimina el indicador de escritura
277
+ typing_indicator.empty()
278
+ # Write full message with placeholder
279
+ message_placeholder.write(full_response)
280
+
281
+ # Add assistant response to chat history
282
+ st.session_state.messages.append(
283
+ dict(
284
+ role=MODEL_ROLE,
285
+ content=st.session_state.chat.history[-1].parts[0].text,
286
+ avatar=AI_AVATAR_ICON,
287
+ )
288
+ )
289
+ st.session_state.gemini_history = st.session_state.chat.history
290
+ # Save to file
291
+ joblib.dump(
292
+ st.session_state.messages,
293
+ f'data/{st.session_state.chat_id}-st_messages',
294
+ )
295
+ joblib.dump(
296
+ st.session_state.gemini_history,
297
+ f'data/{st.session_state.chat_id}-gemini_messages',
298
+ )
299
+ # Si llegamos aquí, la solicitud fue exitosa
300
+ break
301
+
302
+ except Exception as e:
303
+ retry_count += 1
304
+ if retry_count >= max_retries:
305
+ # Si agotamos los reintentos, mostramos un mensaje de error
306
+ with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
307
+ st.error(f"Lo sentimos, estamos experimentando problemas para procesar tu solicitud. Por favor, intenta de nuevo más tarde. Error: {str(e)}")
308
+ st.session_state.messages.append(
309
+ dict(
310
+ role=MODEL_ROLE,
311
+ content=f"Lo sentimos, estamos experimentando problemas para procesar tu solicitud. Por favor, intenta de nuevo más tarde. Error: {str(e)}",
312
+ avatar=AI_AVATAR_ICON,
313
+ )
314
+ )
315
+ joblib.dump(
316
+ st.session_state.messages,
317
+ f'data/{st.session_state.chat_id}-st_messages',
318
+ )
319
+ else:
320
+ # Esperamos antes de reintentar (retroceso exponencial)
321
+ wait_time = (2 ** retry_count) + (time.time() % 1)
322
+ time.sleep(wait_time)