Jeremy Live commited on
Commit
332a246
·
1 Parent(s): 5e701dc

updated the chatbot history

Browse files
Files changed (1) hide show
  1. app.py +116 -102
app.py CHANGED
@@ -288,19 +288,44 @@ def generate_plot(data, x_col, y_col, title, x_label, y_label):
288
 
289
  def convert_to_messages_format(chat_history):
290
  """Convert chat history to the format expected by Gradio 5.x"""
 
 
 
291
  messages = []
292
- for msg in chat_history:
293
- if isinstance(msg, (list, tuple)) and len(msg) == 2:
294
- if msg[0]: # User message
295
- messages.append({"role": "user", "content": msg[0]})
296
- if msg[1]: # Assistant message
297
- messages.append({"role": "assistant", "content": msg[1]})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  return messages
299
 
300
- async def stream_agent_response(question: str, chat_history: List) -> Tuple[List, Dict]:
301
  """Procesa la pregunta del usuario y devuelve la respuesta del agente."""
302
- # Convert to messages format for Gradio 5.x
303
- messages = convert_to_messages_format(chat_history)
 
 
 
 
 
 
 
 
304
 
305
  if not agent:
306
  error_msg = (
@@ -311,16 +336,11 @@ async def stream_agent_response(question: str, chat_history: List) -> Tuple[List
311
  f"3. El modelo de lenguaje esté disponible\n\n"
312
  f"Error: {agent_error}"
313
  )
314
- messages.append({"role": "user", "content": question})
315
  messages.append({"role": "assistant", "content": error_msg})
316
- yield messages, gr.update(visible=False)
317
  return
318
 
319
  try:
320
- # Add user's question to the chat history
321
- messages.append({"role": "user", "content": question})
322
- yield messages, gr.update(visible=False)
323
-
324
  # Execute the agent
325
  response = await agent.ainvoke({"input": question, "chat_history": chat_history})
326
 
@@ -343,13 +363,14 @@ async def stream_agent_response(question: str, chat_history: List) -> Tuple[List
343
 
344
  # Add assistant's response to the chat history
345
  messages.append({"role": "assistant", "content": response_text})
346
- yield messages, gr.update(visible=False)
 
 
347
 
348
  except Exception as e:
349
  error_msg = f"## ❌ Error\n\nOcurrió un error al procesar tu solicitud:\n\n```\n{str(e)}\n```"
350
  messages.append({"role": "assistant", "content": error_msg})
351
- yield messages, gr.update(visible=False)
352
- yield chat_history, gr.update(visible=False)
353
 
354
  # Custom CSS for the app
355
  custom_css = """
@@ -446,7 +467,38 @@ def create_ui():
446
  # Mensaje de estado
447
  if not env_ok:
448
  gr.Warning("⚠️ " + env_message)
449
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
  with gr.Accordion("ℹ️ Estado del sistema", open=not env_ok):
451
  if not DEPENDENCIES_AVAILABLE:
452
  gr.Markdown("""
@@ -508,57 +560,6 @@ def create_ui():
508
  El asistente está listo para responder tus preguntas sobre la base de datos.
509
  """)
510
 
511
- # Interfaz de chat - usando el nuevo formato de mensajes
512
- chatbot = gr.Chatbot(
513
- label="Chat",
514
- height=500,
515
- type="messages" # Usando el nuevo formato de mensajes
516
- )
517
-
518
- # Área de entrada
519
- with gr.Row():
520
- question_input = gr.Textbox(
521
- label="",
522
- placeholder="Escribe tu pregunta sobre la base de datos...",
523
- elem_id="question-input",
524
- container=False,
525
- scale=5,
526
- min_width=300,
527
- max_lines=3,
528
- autofocus=True
529
- )
530
- submit_button = gr.Button(
531
- "Enviar",
532
- elem_id="send-button",
533
- min_width=100,
534
- scale=1,
535
- variant="primary"
536
- )
537
-
538
- # Información del sistema (solo para depuración)
539
- with gr.Accordion("🔍 Información de depuración", open=False):
540
- gr.Markdown("""
541
- ### Estado del sistema
542
- - **Base de datos**: {}
543
- - **Modelo**: {}
544
- - **Modo**: {}
545
- """.format(
546
- f"Conectado a {os.getenv('DB_HOST')}/{os.getenv('DB_NAME')}" if db_connected else "No conectado",
547
- "gemini-2.0-flash" if agent else "No disponible",
548
- "Completo" if agent else "Demo (sin conexión a base de datos)"
549
- ))
550
-
551
- # Mostrar variables de entorno (solo para depuración)
552
- if os.getenv("SHOW_ENV_DEBUG", "false").lower() == "true":
553
- env_vars = {k: "***" if "PASS" in k or "KEY" in k else v
554
- for k, v in os.environ.items()
555
- if k.startswith(('DB_', 'GOOGLE_'))}
556
- gr.Code(
557
- json.dumps(env_vars, indent=2, ensure_ascii=False),
558
- language="json",
559
- label="Variables de entorno"
560
- )
561
-
562
  # Hidden component for streaming output
563
  streaming_output_display = gr.Textbox(visible=False)
564
 
@@ -576,41 +577,53 @@ def create_application():
576
 
577
  logger.info(f"User message: {user_input}")
578
 
579
- # Convert to messages format if needed
580
- if chat_history and isinstance(chat_history[0], list):
581
- chat_history = convert_to_messages_format(chat_history)
582
-
583
- # Add user message to chat history
584
- updated_history = chat_history + [{"role": "user", "content": user_input}]
585
- return "", updated_history
 
 
 
 
 
586
 
587
- async def bot_response(chat_history: List[Dict]) -> Tuple[List[Dict], Dict]:
588
  """Get bot response and update chat history."""
589
- if not chat_history or not chat_history[-1].get("role") == "user":
590
- return chat_history, gr.update(visible=False)
591
-
592
- # Get the last user message
593
- question = chat_history[-1]["content"]
594
- logger.info(f"Processing question: {question}")
595
 
596
- # Convert to old format for backward compatibility with stream_agent_response
597
- old_format = []
598
- for msg in chat_history:
599
- if msg["role"] == "user":
600
- old_format.append([msg["content"], None])
601
- elif msg["role"] == "assistant" and old_format and len(old_format[-1]) == 2 and old_format[-1][1] is None:
602
- old_format[-1][1] = msg["content"]
603
-
604
- # Call the agent and get the response
605
- # We need to consume the async generator and return the last value
606
- last_response = None
607
- async for response in stream_agent_response(question, old_format[:-1]):
608
- last_response = response
609
- return last_response
 
 
 
 
 
 
 
 
 
 
610
 
611
  # Event handlers
612
  with demo:
613
- submit_click = submit_button.click(
 
614
  fn=user_message,
615
  inputs=[question_input, chatbot],
616
  outputs=[question_input, chatbot],
@@ -618,11 +631,12 @@ def create_application():
618
  ).then(
619
  fn=bot_response,
620
  inputs=[chatbot],
621
- outputs=[chatbot, streaming_output_display],
622
  api_name="ask"
623
  )
624
 
625
- question_input.submit(
 
626
  fn=user_message,
627
  inputs=[question_input, chatbot],
628
  outputs=[question_input, chatbot],
@@ -630,7 +644,7 @@ def create_application():
630
  ).then(
631
  fn=bot_response,
632
  inputs=[chatbot],
633
- outputs=[chatbot, streaming_output_display]
634
  )
635
 
636
  return demo
 
288
 
289
  def convert_to_messages_format(chat_history):
290
  """Convert chat history to the format expected by Gradio 5.x"""
291
+ if not chat_history:
292
+ return []
293
+
294
  messages = []
295
+
296
+ # If the first element is a list, assume it's in the old format
297
+ if isinstance(chat_history[0], list):
298
+ for msg in chat_history:
299
+ if isinstance(msg, list) and len(msg) == 2:
300
+ # Format: [user_msg, bot_msg]
301
+ user_msg, bot_msg = msg
302
+ if user_msg:
303
+ messages.append({"role": "user", "content": user_msg})
304
+ if bot_msg:
305
+ messages.append({"role": "assistant", "content": bot_msg})
306
+ else:
307
+ # Assume it's already in the correct format or can be used as is
308
+ for msg in chat_history:
309
+ if isinstance(msg, dict) and "role" in msg and "content" in msg:
310
+ messages.append(msg)
311
+ elif isinstance(msg, str):
312
+ # If it's a string, assume it's a user message
313
+ messages.append({"role": "user", "content": msg})
314
+
315
  return messages
316
 
317
+ async def stream_agent_response(question: str, chat_history: List) -> tuple:
318
  """Procesa la pregunta del usuario y devuelve la respuesta del agente."""
319
+ # Initialize response
320
+ response_text = ""
321
+ messages = []
322
+
323
+ # Add previous chat history
324
+ if chat_history:
325
+ messages.extend(chat_history)
326
+
327
+ # Add user's question
328
+ messages.append({"role": "user", "content": question})
329
 
330
  if not agent:
331
  error_msg = (
 
336
  f"3. El modelo de lenguaje esté disponible\n\n"
337
  f"Error: {agent_error}"
338
  )
 
339
  messages.append({"role": "assistant", "content": error_msg})
340
+ yield messages
341
  return
342
 
343
  try:
 
 
 
 
344
  # Execute the agent
345
  response = await agent.ainvoke({"input": question, "chat_history": chat_history})
346
 
 
363
 
364
  # Add assistant's response to the chat history
365
  messages.append({"role": "assistant", "content": response_text})
366
+
367
+ # Yield the updated messages
368
+ yield messages
369
 
370
  except Exception as e:
371
  error_msg = f"## ❌ Error\n\nOcurrió un error al procesar tu solicitud:\n\n```\n{str(e)}\n```"
372
  messages.append({"role": "assistant", "content": error_msg})
373
+ yield messages
 
374
 
375
  # Custom CSS for the app
376
  custom_css = """
 
467
  # Mensaje de estado
468
  if not env_ok:
469
  gr.Warning("⚠️ " + env_message)
470
+
471
+ # Chatbot component
472
+ chatbot = gr.Chatbot(
473
+ label="Chat",
474
+ height=500,
475
+ show_label=True,
476
+ container=True,
477
+ type="messages",
478
+ elem_id="chatbot"
479
+ )
480
+
481
+ # Input area
482
+ with gr.Row():
483
+ question_input = gr.Textbox(
484
+ label="",
485
+ placeholder="Escribe tu pregunta aquí...",
486
+ container=False,
487
+ scale=5,
488
+ min_width=300,
489
+ max_lines=3,
490
+ autofocus=True,
491
+ elem_id="question-input"
492
+ )
493
+ submit_button = gr.Button(
494
+ "Enviar",
495
+ variant="primary",
496
+ min_width=100,
497
+ scale=1,
498
+ elem_id="send-button"
499
+ )
500
+
501
+ # System status
502
  with gr.Accordion("ℹ️ Estado del sistema", open=not env_ok):
503
  if not DEPENDENCIES_AVAILABLE:
504
  gr.Markdown("""
 
560
  El asistente está listo para responder tus preguntas sobre la base de datos.
561
  """)
562
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  # Hidden component for streaming output
564
  streaming_output_display = gr.Textbox(visible=False)
565
 
 
577
 
578
  logger.info(f"User message: {user_input}")
579
 
580
+ # Initialize chat history if needed
581
+ if chat_history is None:
582
+ chat_history = []
583
+
584
+ # Add user message
585
+ chat_history.append({"role": "user", "content": user_input})
586
+
587
+ # Add empty assistant response
588
+ chat_history.append({"role": "assistant", "content": ""})
589
+
590
+ # Clear the input
591
+ return "", chat_history
592
 
593
+ async def bot_response(chat_history: List[Dict]) -> List[Dict]:
594
  """Get bot response and update chat history."""
595
+ if not chat_history or chat_history[-1]["role"] != "assistant":
596
+ return chat_history
 
 
 
 
597
 
598
+ try:
599
+ # Get the user's question (second to last message)
600
+ if len(chat_history) < 2:
601
+ return chat_history
602
+
603
+ question = chat_history[-2]["content"]
604
+ logger.info(f"Processing question: {question}")
605
+
606
+ # Call the agent and stream the response
607
+ async for response in stream_agent_response(question, chat_history[:-2]):
608
+ if isinstance(response, tuple) and len(response) > 0 and isinstance(response[0], list):
609
+ messages = response[0]
610
+ if messages and messages[-1]["role"] == "assistant":
611
+ # Update the assistant's response
612
+ chat_history[-1] = messages[-1]
613
+ yield chat_history
614
+
615
+ logger.info("Response generation complete")
616
+
617
+ except Exception as e:
618
+ error_msg = f"Error al procesar la solicitud: {str(e)}"
619
+ logger.error(error_msg, exc_info=True)
620
+ chat_history[-1]["content"] = error_msg
621
+ yield chat_history
622
 
623
  # Event handlers
624
  with demo:
625
+ # Handle form submission
626
+ msg_submit = question_input.submit(
627
  fn=user_message,
628
  inputs=[question_input, chatbot],
629
  outputs=[question_input, chatbot],
 
631
  ).then(
632
  fn=bot_response,
633
  inputs=[chatbot],
634
+ outputs=[chatbot],
635
  api_name="ask"
636
  )
637
 
638
+ # Handle button click
639
+ btn_click = submit_button.click(
640
  fn=user_message,
641
  inputs=[question_input, chatbot],
642
  outputs=[question_input, chatbot],
 
644
  ).then(
645
  fn=bot_response,
646
  inputs=[chatbot],
647
+ outputs=[chatbot]
648
  )
649
 
650
  return demo