pbesa 4.0.13__tar.gz → 4.0.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. {pbesa-4.0.13 → pbesa-4.0.14}/PKG-INFO +1 -1
  2. pbesa-4.0.14/pbesa/celulas/celula_preguntas.py +41 -0
  3. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/cognitive.py +159 -96
  4. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/models.py +43 -8
  5. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/dispatcher_team.py +4 -1
  6. pbesa-4.0.14/pbesa/social/prompts.py +213 -0
  7. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa.egg-info/PKG-INFO +1 -1
  8. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa.egg-info/SOURCES.txt +1 -0
  9. {pbesa-4.0.13 → pbesa-4.0.14}/setup.py +1 -1
  10. pbesa-4.0.13/pbesa/social/prompts.py +0 -90
  11. {pbesa-4.0.13 → pbesa-4.0.14}/.gitignore +0 -0
  12. {pbesa-4.0.13 → pbesa-4.0.14}/LICENSE +0 -0
  13. {pbesa-4.0.13 → pbesa-4.0.14}/LICENSE.txt +0 -0
  14. {pbesa-4.0.13 → pbesa-4.0.14}/MANIFEST +0 -0
  15. {pbesa-4.0.13 → pbesa-4.0.14}/README.md +0 -0
  16. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/db.sqlite3 +0 -0
  17. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/__init__.py +0 -0
  18. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/__pycache__/__init__.cpython-36.pyc +0 -0
  19. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/__pycache__/pbesa.cpython-36.pyc +0 -0
  20. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/__pycache__/settings.cpython-36.pyc +0 -0
  21. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/__pycache__/urls.cpython-36.pyc +0 -0
  22. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/__pycache__/wsgi.cpython-36.pyc +0 -0
  23. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/asgi.py +0 -0
  24. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/pbesa.py +0 -0
  25. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/settings.py +0 -0
  26. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/urls.py +0 -0
  27. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/helloworld/wsgi.py +0 -0
  28. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/manage.py +0 -0
  29. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__init__.py +0 -0
  30. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__pycache__/__init__.cpython-36.pyc +0 -0
  31. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__pycache__/admin.cpython-36.pyc +0 -0
  32. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__pycache__/apps.cpython-36.pyc +0 -0
  33. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__pycache__/models.cpython-36.pyc +0 -0
  34. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__pycache__/urls.cpython-36.pyc +0 -0
  35. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/__pycache__/views.cpython-36.pyc +0 -0
  36. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/admin.py +0 -0
  37. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/apps.py +0 -0
  38. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/controller/__pycache__/translatecontroller.cpython-36.pyc +0 -0
  39. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/controller/__pycache__/translatedelegate.cpython-36.pyc +0 -0
  40. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/controller/__pycache__/translateresponse.cpython-36.pyc +0 -0
  41. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/controller/translatecontroller.py +0 -0
  42. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/controller/translatedelegate.py +0 -0
  43. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/controller/translateresponse.py +0 -0
  44. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/worker/__pycache__/translatetask.cpython-36.pyc +0 -0
  45. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/worker/__pycache__/workeragent.cpython-36.pyc +0 -0
  46. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/worker/translatetask.py +0 -0
  47. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/mas/worker/workeragent.py +0 -0
  48. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/migrations/__init__.py +0 -0
  49. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/migrations/__pycache__/__init__.cpython-36.pyc +0 -0
  50. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/models.py +0 -0
  51. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/tests.py +0 -0
  52. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/urls.py +0 -0
  53. {pbesa-4.0.13 → pbesa-4.0.14}/examples/django/helloworld/translate/views.py +0 -0
  54. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/__pycache__/countercontroller.cpython-36.pyc +0 -0
  55. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/__pycache__/counterdelegate.cpython-36.pyc +0 -0
  56. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/__pycache__/counterresponse.cpython-36.pyc +0 -0
  57. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/__pycache__/translatecontroller.cpython-36.pyc +0 -0
  58. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/__pycache__/translatedelegate.cpython-36.pyc +0 -0
  59. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/__pycache__/translateresponse.cpython-36.pyc +0 -0
  60. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/countercontroller.py +0 -0
  61. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/counterdelegate.py +0 -0
  62. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/controller/counterresponse.py +0 -0
  63. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/worker/__pycache__/counteragent.cpython-36.pyc +0 -0
  64. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/worker/__pycache__/countertask.cpython-36.pyc +0 -0
  65. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/worker/__pycache__/translatetask.cpython-36.pyc +0 -0
  66. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/worker/__pycache__/workeragent.cpython-36.pyc +0 -0
  67. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/worker/counteragent.py +0 -0
  68. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/mas/worker/countertask.py +0 -0
  69. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/remote_a.py +0 -0
  70. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/remote_b.py +0 -0
  71. {pbesa-4.0.13 → pbesa-4.0.14}/examples/remote/remote_c.py +0 -0
  72. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/__init__.py +0 -0
  73. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/__init__.py +0 -0
  74. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/celula_casos.py +0 -0
  75. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/celula_consultas.py +0 -0
  76. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/celula_datos_identificables.py +0 -0
  77. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/celula_generar_documento.py +0 -0
  78. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/celula_saludos.py +0 -0
  79. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/celulas/web.py +0 -0
  80. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/__init__.py +0 -0
  81. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/adapter.py +0 -0
  82. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/agent.py +0 -0
  83. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/io/__init__.py +0 -0
  84. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/io/system_file.py +0 -0
  85. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/io/tcp_server.py +0 -0
  86. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/res/__init__.py +0 -0
  87. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/res/__pycache__/__init__.cpython-36.pyc +0 -0
  88. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/res/__pycache__/__init__.cpython-37.pyc +0 -0
  89. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/res/__pycache__/__init__.cpython-38.pyc +0 -0
  90. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/res/__pycache__/__init__.cpython-39.pyc +0 -0
  91. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/res/conf.json +0 -0
  92. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/util.py +0 -0
  93. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/kernel/world.py +0 -0
  94. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/mas.py +0 -0
  95. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/remote/__init__.py +0 -0
  96. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/remote/adm_listener.py +0 -0
  97. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/remote/adm_listener_handler.py +0 -0
  98. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/remote/exceptions.py +0 -0
  99. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/remote/remote_adm.py +0 -0
  100. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/remote/remote_adm_handler.py +0 -0
  101. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/__init__.py +0 -0
  102. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/collaborative_team.py +0 -0
  103. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/delegator.py +0 -0
  104. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/delegator_team.py +0 -0
  105. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/dialog.py +0 -0
  106. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/selected_dispatcher_team.py +0 -0
  107. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/templates.py +0 -0
  108. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa/social/worker.py +0 -0
  109. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa.egg-info/dependency_links.txt +0 -0
  110. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa.egg-info/requires.txt +0 -0
  111. {pbesa-4.0.13 → pbesa-4.0.14}/pbesa.egg-info/top_level.txt +0 -0
  112. {pbesa-4.0.13 → pbesa-4.0.14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pbesa
3
- Version: 4.0.13
3
+ Version: 4.0.14
4
4
  License-File: LICENSE
5
5
  License-File: LICENSE.txt
6
6
  Requires-Dist: pymongo>=4.6.3
@@ -0,0 +1,41 @@
1
+ import logging
2
+
3
+ PROMPT = """
4
+ Eres un clasificador de preguntas. Tu tarea es analizar el siguiente texto y determinar si contiene preguntas.
5
+
6
+ Responde únicamente con una de estas opciones:
7
+ - CONTIENE
8
+ - NO_CONTIENE
9
+
10
+ **Definición de pregunta**: Una pregunta es una expresión que busca obtener información o aclaración sobre un tema específico. Esto incluye preguntas directas, indirectas y retóricas. No se consideran preguntas las afirmaciones o comentarios que no buscan respuesta.
11
+
12
+ Ejemplos:
13
+ - "Hola, ¿cómo estás?" → CONTIENE
14
+ - "Buenos días, equipo" → NO_CONTIENE
15
+ - "¿Cómo se hace este análisis?" → CONTIENE
16
+ - "Ey, qué más" → NO_CONTIENE
17
+ - "Necesito ayuda con el código" → NO_CONTIENE
18
+ - "Saludos" → NO_CONTIENE
19
+
20
+ Texto: "%s"
21
+
22
+ Clasificación:
23
+ """
24
+
25
+ # Efectua la inferencia del modelo.
26
+ def derive(service, text, max_tkns=4096) -> any:
27
+ try:
28
+ logging.info(f"Procesando: {text}")
29
+ tmp_work_memory = []
30
+ prompt = PROMPT % text
31
+ tmp_work_memory.append({"role": "user", "content": prompt})
32
+ res = service.generate(tmp_work_memory, max_tokens=max_tkns)
33
+ logging.info(f"Respuesta: {res}")
34
+ if not res or res == "":
35
+ res = text
36
+ logging.warning(f"No obtener una respuesta.")
37
+ return res
38
+ except Exception as e:
39
+ logging.error(f"Error al procesar: {text}")
40
+ logging.error(e)
41
+ return None
@@ -27,7 +27,7 @@ from pbesa.social.dialog import (
27
27
  ActionNode, DeclarativeNode, GotoNode)
28
28
  from .celulas import (celula_casos, celula_consultas, celula_saludos, celula_datos_identificables,
29
29
  celula_generar_documento)
30
- from pbesa.social.prompts import CLASSIFICATION_PROMPT, DERIVE_PROMPT, RECOVERY_PROMPT, ADAPT_PROMPT
30
+ from pbesa.social.prompts import ANALIZER_PROMPT, CLASSIFICATION_PROMPT, DERIVE_PROMPT, RECOVERY_PROMPT, ADAPT_PROMPT, SINTETIZER_PROMPT
31
31
 
32
32
  # --------------------------------------------------------
33
33
  # Define DTOs
@@ -556,6 +556,10 @@ class Dialog(ABC):
556
556
  self.__vertices = []
557
557
  # Define visited nodes
558
558
  self.__visited_nodes = 0
559
+ # Define alter work memory
560
+ self.__attemps = 1
561
+ self.__analazer_work_memory:list = []
562
+ self.__sintetizer_work_memory:list = []
559
563
 
560
564
  def setup_world(self):
561
565
  """ Set up model method """
@@ -660,11 +664,11 @@ class Dialog(ABC):
660
664
  self.__visited_nodes = 0
661
665
  self.__vertices = []
662
666
 
663
- def notify(self, text):
667
+ def notify(self, session_id, text):
664
668
  try:
665
669
  canales = self.state['canales']
666
670
  canal = canales.get("Webhook")
667
- session_id = self.state['session_id']
671
+ #session_id = self.state['session_id']
668
672
  dto = {
669
673
  "session_id": session_id,
670
674
  "text": text[0:100]
@@ -676,9 +680,9 @@ class Dialog(ABC):
676
680
  logging.warning(f"Notificación no enviada: {text}")
677
681
  except Exception as e:
678
682
  logging.error(f"Error al enviar notificación: {text}")
679
- logging.erro(f"Error: {e}")
683
+ logging.error(f"Error: {e}")
680
684
 
681
- def team_inquiry(self, team, data, operation, session_flag) -> str:
685
+ def team_inquiry(self, session, team, data, operation, session_flag) -> str:
682
686
  try:
683
687
  dto = None
684
688
  canales = self.state['canales']
@@ -686,7 +690,7 @@ class Dialog(ABC):
686
690
  if session_flag:
687
691
  # Actualiza la sesion
688
692
  session_manager = self.state['session_manager']
689
- session_manager.update_session(self.state['session_id'], {
693
+ session_manager.update_session(session['session_id'], {
690
694
  'team': team,
691
695
  'owner': team,
692
696
  'performative': DialogState.START,
@@ -695,7 +699,7 @@ class Dialog(ABC):
695
699
  dto = {
696
700
  "data": {
697
701
  'text': data,
698
- 'session_id': self.state['session_id'],
702
+ 'session_id': session['session_id'],
699
703
  },
700
704
  }
701
705
  # Evia mensaje a los agentes remotos
@@ -712,8 +716,8 @@ class Dialog(ABC):
712
716
  "data": {
713
717
  'text': data,
714
718
  'operation': operation,
715
- 'id_conversacion': self.state['id_conversacion'],
716
- 'session_id': self.state['session_id'],
719
+ 'id_conversacion': session['id_conversacion'],
720
+ 'session_id': session['session_id'],
717
721
  },
718
722
  }
719
723
  else:
@@ -742,7 +746,7 @@ class Dialog(ABC):
742
746
  else:
743
747
  return ""
744
748
 
745
- def recovery(self, query):
749
+ def recovery(self, session_id, query):
746
750
  try:
747
751
  prompt = RECOVERY_PROMPT % query
748
752
  temp_work_memory = [{"role": "user", "content": prompt}]
@@ -754,12 +758,98 @@ class Dialog(ABC):
754
758
  logging.info(f"------------RESET---------------")
755
759
  logging.info(f"Recovery from: {self.__recovery['performative']}")
756
760
  self.reset()
757
- self.notify("STOP")
761
+ self.notify(session_id, "STOP")
758
762
  return "Web", DialogState.START, self.RECOVERY_MSG, "Web"
759
763
  except Exception as e:
760
764
  return self.RECOVERY_MSG
761
-
762
- def transition(self, owner, dialog_state, query, team_source=False) -> str:
765
+
766
+ def stage_one_classification(self, session_id, messages, attemps, query):
767
+ """ Stage one classification """
768
+ res = ""
769
+ #evaluating = True
770
+ dicriminador = None
771
+ logging.info(f"------------Flujo de excepcion---------------")
772
+ self.notify(session_id, "identificando intención...")
773
+
774
+ logging.info(f"Intento: {attemps}")
775
+ # Obtiene discriminadores
776
+ # Verifica si es un saludo
777
+ if attemps == 1:
778
+ saludo = celula_saludos.derive(self.__ai_service, query, max_tkns=10)
779
+ else:
780
+ saludo = "NO_SALUDO"
781
+ # De la forma user, system y de messages
782
+ # genera un texto discriminando los tipos de mensajes
783
+ history = ""
784
+ for message in messages:
785
+ if message['user']:
786
+ history += f"user: {message['text']}\n"
787
+ else:
788
+ history += f"system: {message['text']}\n"
789
+ # User
790
+ #history += f"user: {query}\n"
791
+
792
+ # Actyaliza la memoria de trabajo
793
+ prompt = ANALIZER_PROMPT % history
794
+ self.__analazer_work_memory:list = [{"role": "user", "content": prompt}]
795
+ if attemps > 1:
796
+ # Desde la seegunda iteeraccion de la
797
+ # conversacion, se utiliza el sintentizador
798
+ prompt = SINTETIZER_PROMPT % history
799
+ self.__sintetizer_work_memory:list = [{"role": "user", "content": prompt}]
800
+ logging.info("\n\n\n--------------SINTETIZER------------------")
801
+ logging.info("\n%s", json.dumps(self.__sintetizer_work_memory, indent=4))
802
+ logging.info("\n\n\n")
803
+ query = self.__ai_service.generate(self.__sintetizer_work_memory, max_tokens=10)
804
+ res = self.get_text(query)
805
+ query = res
806
+ logging.info(f"Thought: {query}")
807
+ # Verifica si es una consulta o un caso
808
+ caso = celula_casos.derive(self.__ai_service, query, max_tkns=10)
809
+ consulta = celula_consultas.derive(self.__ai_service, query, max_tkns=10)
810
+ # Verifica si es un saludo, consulta o caso
811
+ es_saludo = ("SALUDO" in saludo) and ("NO_PREGUNTA" in consulta) and ("NO_QUEJA_DEMANDA" in caso) and not ("NO_SALUDO" in saludo)
812
+ es_consulta = ("PREGUNTA_O_SOLICITUD" in consulta) and ("NO_QUEJA_DEMANDA" in caso) and ("NO_SALUDO" in saludo) and not ("NO_PREGUNTA" in consulta)
813
+ es_caso = ("QUEJA_DEMANDA" in caso) and ("NO_PREGUNTA" in consulta) and ("NO_SALUDO" in saludo) and not ("NO_QUEJA_DEMANDA" in caso)
814
+ print("\n------------------- Clase --------------------------")
815
+ logging.info(f"==> Saludo: {saludo}, Consulta: {consulta}, Caso: {caso}")
816
+ logging.info(f"==> Es saludo: {es_saludo}, Es consulta: {es_consulta}, Es caso: {es_caso}")
817
+ print("\n-----------------------------------------------------")
818
+ # Verifica los casos
819
+ if es_saludo or es_consulta or es_caso:
820
+ logging.info("Respuesta Clara")
821
+ if es_saludo:
822
+ dicriminador = "saluda"
823
+ elif es_consulta:
824
+ dicriminador = "consulta"
825
+ else:
826
+ dicriminador = "caso"
827
+ #evaluating = False
828
+ self.notify(session_id, f"fase uno es {dicriminador}...")
829
+ res = query
830
+ else:
831
+ logging.info("Respuesta con ambiguedad")
832
+ self.notify(session_id, "identificando ambiguedad...")
833
+ self.__analazer_work_memory.append({"role": "user", "content": query})
834
+ logging.info("\n\n\n--------------ANALIZER------------------")
835
+ logging.info("\n%s", json.dumps(self.__analazer_work_memory, indent=4))
836
+ logging.info("------------------------------------------\n\n\n")
837
+ res = self.__ai_service.generate(self.__analazer_work_memory, max_tokens=10)
838
+ logging.info(f"Thought: {res}")
839
+ self.__analazer_work_memory.append({"role": "system", "content": query})
840
+ self.__sintetizer_work_memory.append({"role": "system", "content": query})
841
+ #if caso == "QUEJA_DEMANDA":
842
+ # dicriminador = "caso"
843
+ #elif consulta == "PREGUNTA_O_SOLICITUD":
844
+ # dicriminador = "consulta"
845
+ #elif saludo == "SALUDO":
846
+ # dicriminador = "saluda"
847
+ #logging.info(f"==> Discriminador: {dicriminador}")
848
+ #if dicriminador == "Ninguno":
849
+ # dicriminador = "consulta"
850
+ return dicriminador, res
851
+
852
+ def transition(self, session, owner, dialog_state, query, team_source=False) -> str:
763
853
  try:
764
854
  res = ""
765
855
  logging.info(f"TOPTQ: {owner} - {dialog_state} - {team_source} - {query}")
@@ -780,44 +870,26 @@ class Dialog(ABC):
780
870
  #------------------------------
781
871
  if owner == "Web" and dialog_state == DialogState.START:
782
872
  logging.info(f"TOPTQ: {owner} - {dialog_state} - {team_source} - {query}")
783
- logging.info(f"------------Flujo de excepcion---------------")
784
- self.notify("identificando intencion...")
785
- # Obtiene discriminadores
786
- caso = celula_casos.derive(self.__ai_service, query, max_tkns=10)
787
- consulta = celula_consultas.derive(self.__ai_service, query, max_tkns=10)
788
- saludo = celula_saludos.derive(self.__ai_service, query, max_tkns=10)
789
- # Verifica si es un saludo
790
- es_saludo = ("SALUDO" in saludo) and ("NO_PREGUNTA" in consulta) and ("NO_QUEJA_DEMANDA" in caso) and not ("NO_SALUDO" in saludo)
791
- es_consulta = ("PREGUNTA_O_SOLICITUD" in consulta) and ("NO_QUEJA_DEMANDA" in caso) and ("NO_SALUDO" in saludo) and not ("NO_PREGUNTA" in consulta)
792
- es_caso = ("QUEJA_DEMANDA" in caso) and ("NO_PREGUNTA" in consulta) and ("NO_SALUDO" in saludo) and not ("NO_QUEJA_DEMANDA" in caso)
793
-
794
- print("\n--- Clase ---")
795
- logging.info(f"==> Saludo: {saludo}, Consulta: {consulta}, Caso: {caso}")
796
- logging.info(f"==> Es saludo: {es_saludo}, Es consulta: {es_consulta}, Es caso: {es_caso}")
797
- # Verifica los casos
798
- dicriminador = "Ninguno"
799
- if es_saludo or es_consulta or es_caso:
800
- logging.info("Respuesta Clara")
801
- self.notify("discriminando...")
802
- if es_saludo:
803
- dicriminador = "saluda"
804
- elif es_consulta:
805
- dicriminador = "consulta"
806
- elif es_caso:
807
- dicriminador = "caso"
808
- else:
809
- logging.info("Respuesta con ambiguedad")
810
- self.notify("identificando ambiguedad...")
811
- if caso == "QUEJA_DEMANDA":
812
- dicriminador = "caso"
813
- elif consulta == "PREGUNTA_O_SOLICITUD":
814
- dicriminador = "consulta"
815
- elif saludo == "SALUDO":
816
- dicriminador = "saluda"
817
- logging.info(f"==> Discriminador: {dicriminador}")
818
- if dicriminador == "Ninguno":
819
- dicriminador = "consulta"
820
- print("---------------------\n")
873
+ session_manager = self.state['session_manager']
874
+ conversation = session_manager.get_conversation(session['id_conversacion'])
875
+ attemps = conversation.get('attemps', 1)
876
+ dicriminador, res = self.stage_one_classification(session['session_id'], conversation['messages'], attemps, query)
877
+ conversation['attemps'] = attemps + 1
878
+ session_manager.update_conversation(session['id_conversacion'], conversation)
879
+ logging.info(f"Discriminador: {dicriminador}")
880
+ # Limpia la memoria de trabajo
881
+ # Para que el agente la utilice en
882
+ # Otra conversacion
883
+ self.__analazer_work_memory:list = []
884
+ self.__sintetizer_work_memory:list = []
885
+ if not dicriminador:
886
+ # Una nueva iteración de analisis
887
+ logging.info(f"------------RESET---------------")
888
+ logging.info(f"Recovery from: {self.__recovery['performative']}")
889
+ self.reset()
890
+ self.notify(session['session_id'], "STOP")
891
+ return "Web", DialogState.START, res, "Web"
892
+ query = res
821
893
  #--------------------------
822
894
  # Obtiene los hijos del
823
895
  # nodo
@@ -830,7 +902,6 @@ class Dialog(ABC):
830
902
  children = node
831
903
  #--------------------------
832
904
  # Flujo de selección
833
- self.notify("flujo de seleccion...")
834
905
  if children and len(children)> 1:
835
906
  logging.info(f"--> Más de una opción.")
836
907
  options = ""
@@ -838,22 +909,22 @@ class Dialog(ABC):
838
909
  for item in children:
839
910
  if dicriminador in item.text:
840
911
  select_node = item
841
- break
912
+ break
842
913
  else:
843
914
  #------------------------------
844
915
  # Fulo normal
845
916
  #------------------------------
846
917
  logging.info("Flujo normal")
847
- self.notify("identificando concepto...")
918
+ self.notify(session['session_id'], "identificando concepto...")
848
919
  #----------------------
849
920
  # Verifica que exista
850
921
  # la performativa
851
922
  if not dialog_state in self.__dfa:
852
- self.notify("concepto no encontrado")
853
- return self.recovery(query)
923
+ self.notify(session['session_id'], "concepto no encontrado")
924
+ return self.recovery(session['session_id'], query)
854
925
  # Performativa encontrada
855
926
  children = None
856
- self.notify("concepto encontrado")
927
+ self.notify(session['session_id'], "concepto encontrado")
857
928
  #----------------------
858
929
  # Obtiene los hijos del
859
930
  # nodo
@@ -866,7 +937,6 @@ class Dialog(ABC):
866
937
  #----------------------
867
938
  # Flujo de selección
868
939
  select_node = None
869
- self.notify("flujo de seleccion...")
870
940
  if children and len(children)> 1:
871
941
  logging.info(f"--> Más de una opción.")
872
942
  options = ""
@@ -897,13 +967,13 @@ class Dialog(ABC):
897
967
  logging.info("???> Es un nodo terminal o iniciador")
898
968
  logging.warning(f"???> Es un nodo terminal o iniciador: {node}")
899
969
  logging.warning(f"???> Es un nodo terminal o iniciador: {node}")
900
- return self.recovery(query)
970
+ return self.recovery(session['session_id'], query)
901
971
 
902
972
  # Verifica si el nodo fue seleccionado
903
973
  if not select_node:
904
974
  logging.warning(f"???> No se seleccionó ningún nodo")
905
975
  logging.info(f"------------RESET---------------")
906
- self.notify("STOP")
976
+ self.notify(session['session_id'], "STOP")
907
977
  self.reset()
908
978
  return "Web", DialogState.START, self.RECOVERY_MSG, "Web"
909
979
 
@@ -943,9 +1013,8 @@ class Dialog(ABC):
943
1013
  node = node[0]
944
1014
  else:
945
1015
  logging.info(f"-> !!!!!!!!!!!!!! Concepto no encontrado ????????????????")
946
- return self.recovery(query)
1016
+ return self.recovery(session['session_id'], query)
947
1017
  logging.info(f"Flujo normal: {res}")
948
- self.notify(res)
949
1018
  #---------------------------
950
1019
  # Verifica si el nuevo nodo
951
1020
  # es un nodo de salto
@@ -967,13 +1036,13 @@ class Dialog(ABC):
967
1036
  #logging.info(f"-> Actualiza r-WM: {res}")
968
1037
  #---------------------------
969
1038
  # Efectua inferencia
970
- new_owner, new_dialog_state, res, team = self.do_transition(owner, node, query)
1039
+ new_owner, new_dialog_state, res, team = self.do_transition(session, owner, node, query)
971
1040
  if res and not res == "ERROR" and isinstance(res, str):
972
1041
  res = self.get_text(res)
973
1042
  return new_owner, new_dialog_state, res, team
974
1043
  else:
975
1044
  logging.info(f"------------RESET---------------")
976
- self.notify("STOP")
1045
+ self.notify(session['session_id'], "STOP")
977
1046
  self.reset()
978
1047
  return "Web", DialogState.START, self.RECOVERY_MSG, "Web"
979
1048
  logging.info("END: do_transition")
@@ -981,22 +1050,22 @@ class Dialog(ABC):
981
1050
  traceback.print_exc()
982
1051
  logging.info(f"------------RESET---------------")
983
1052
  self.reset()
984
- self.notify("STOP")
1053
+ self.notify(session['session_id'], "STOP")
985
1054
  return owner, DialogState.START, "Lo lamento, no puedo responder en este momento", owner
986
1055
 
987
- def do_transition(self, owner, node, query) -> str:
1056
+ def do_transition(self, session, owner, node, query) -> str:
988
1057
  """ Generate method
989
1058
  :return: str
990
1059
  """
991
1060
  try:
992
1061
  if isinstance(node, ActionNode):
993
- self.notify("realizando acción...")
1062
+ self.notify(session['session_id'], "realizando acción...")
994
1063
  #------------------------------
995
1064
  # Accion
996
1065
  #------------------------------
997
1066
  logging.info(f"-> node action: {node.action}")
998
1067
  if node.tool and not node.tool == "Ninguno":
999
- self.notify("aplicando herramienta...")
1068
+ self.notify(session['session_id'], "aplicando herramienta...")
1000
1069
  logging.info(f"-> node tool: {node.tool}")
1001
1070
 
1002
1071
  res = query
@@ -1012,18 +1081,18 @@ class Dialog(ABC):
1012
1081
  res = self.get_text(res)
1013
1082
  # Check if res is empty
1014
1083
  if not res or res == "":
1015
- self.notify("no pude hacer uso de la herramienta")
1016
- return self.recovery(query)
1084
+ self.notify(session['session_id'], "no pude hacer uso de la herramienta")
1085
+ return self.recovery(session['session_id'], query)
1017
1086
  logging.info(f"-> node tool: envia -> {res}")
1018
- res = self.team_inquiry(node.team, res, node.tool, False)
1087
+ res = self.team_inquiry(session, node.team, res, node.tool, False)
1019
1088
 
1020
1089
  if res and not res == "ERROR" and not isinstance(res, str):
1021
1090
  logging.info(f"COMANDO -> node tool: recibe -> {res}")
1022
1091
  self.reset()
1023
- self.notify("STOP")
1092
+ self.notify(session['session_id'], "STOP")
1024
1093
  return "Web", DialogState.START, res, "Web"
1025
1094
  else:
1026
- self.notify("realizando llamada...")
1095
+ self.notify(session['session_id'], "realizando llamada...")
1027
1096
  #------------------------------
1028
1097
  # Lllamada
1029
1098
  #------------------------------
@@ -1046,18 +1115,16 @@ class Dialog(ABC):
1046
1115
  self.__work_memory.append({"role": "system", "content": res})
1047
1116
  # Check if res is empty
1048
1117
  if not res or res == "":
1049
- self.notify(f"no pude contactar al agente: {node.team}")
1050
- return self.recovery(query)
1051
- self.notify(f"le envio al agente {node.team}: {res}")
1118
+ return self.recovery(session['session_id'], query)
1052
1119
  logging.info(f"-> node team -> envia: {res}")
1053
- res = self.team_inquiry(node.team, res, None, True)
1120
+ res = self.team_inquiry(session, node.team, res, None, True)
1054
1121
  if res and not res == "ERROR" and not res == "":
1055
1122
  logging.info(f"------------RESET---------------")
1056
1123
  self.reset()
1057
- self.notify("STOP")
1124
+ self.notify(session['session_id'], "STOP")
1058
1125
  return node.team, DialogState.START, res, node.team
1059
1126
  else:
1060
- return self.recovery(query)
1127
+ return self.recovery(session['session_id'], query)
1061
1128
  else:
1062
1129
 
1063
1130
  logging.info("-> node team -> continua")
@@ -1074,34 +1141,31 @@ class Dialog(ABC):
1074
1141
  self.__work_memory.append({"role": "system", "content": res})
1075
1142
  # Check if res is empty
1076
1143
  if not res or res == "":
1077
- self.notify(f"no pude contactar al agente: {node.team}")
1078
- return self.recovery(query)
1079
- self.notify(f"le envio al agente {node.team}: {res}")
1080
- res = self.team_inquiry(node.team, res, node.tool, False)
1081
- self.notify(f"continuando con díalogo")
1144
+ return self.recovery(session['session_id'], query)
1145
+ res = self.team_inquiry(session, node.team, res, node.tool, False)
1082
1146
 
1083
1147
  # Adiciona el texto al work memory
1084
1148
  if res and not res == "ERROR" and not res == "":
1085
1149
  logging.info(f"-> Adicion WM node team -> text: {res}")
1086
1150
  self.__work_memory.append({"role": "system", "content": res})
1087
1151
  else:
1088
- return self.recovery(query)
1152
+ return self.recovery(session['session_id'], query)
1089
1153
  logging.info("#########> Procesa respuesta del equipo en profundidad")
1090
1154
  # Verifica si se alcanzó el límite de profundidad
1091
1155
  self.__deep_count += 1
1092
1156
  if self.__deep_count < self.__deep_limit:
1093
- self.notify("efectuando inferencia en profundidad")
1094
- return self.transition(owner, node.performative, res, True)
1157
+ self.notify(session['session_id'], "efectuando inferencia en profundidad")
1158
+ return self.transition(session, owner, node.performative, res, True)
1095
1159
  else:
1096
- self.notify(f"se alcanzó el límite de profundidad: {self.__deep_count}")
1160
+ self.notify(session['session_id'], f"se alcanzó el límite de profundidad: {self.__deep_count}")
1097
1161
  self.__deep_count = 0
1098
1162
  logging.info("-> node team -> deep limit")
1099
1163
  logging.info(f"------------RESET---------------")
1100
- self.notify("STOP")
1164
+ self.notify(session['session_id'], "STOP")
1101
1165
  self.reset()
1102
1166
  return "Web", DialogState.START, self.RECOVERY_MSG, "Web"
1103
1167
  else:
1104
- self.notify("efectuando inferencia...")
1168
+ self.notify(session['session_id'], "efectuando inferencia...")
1105
1169
  logging.info(f"D -> node: {node.text}")
1106
1170
  self.__work_memory.append({"role": "user", "content": node.text})
1107
1171
  logging.info(f"=> !!!!: {query}")
@@ -1113,26 +1177,25 @@ class Dialog(ABC):
1113
1177
  self.__work_memory.append({"role": "system", "content": res})
1114
1178
  # Check if res is empty
1115
1179
  if not res or res == "":
1116
- return self.recovery(query)
1180
+ return self.recovery(session['session_id'], query)
1117
1181
  logging.info(f"=> Thought DEEP: {res}")
1118
- self.notify(f"Realizando inferencia: {res}")
1119
1182
  new_dialog_state = node.performative
1120
1183
  if not node.is_terminal:
1121
- self.notify(f"continuando díalogo de inferencia")
1184
+ self.notify(session['session_id'], f"continuando díalogo de inferencia")
1122
1185
  return owner, new_dialog_state, res, owner
1123
- self.notify(f"finalizando díalogo de inferencia")
1186
+ self.notify(session['session_id'], f"finalizando díalogo de inferencia")
1124
1187
  logging.info(f"Tipe node: {type(node)}")
1125
1188
  logging.info(f"$$$> new_owner: {owner} new_dialog_state: {new_dialog_state}")
1126
1189
  #logging.info(f"------------RESET---------------")
1127
1190
  #self.reset()
1128
- self.notify("STOP")
1191
+ self.notify(session['session_id'], "STOP")
1129
1192
  return "Web", DialogState.START, res, "Web"
1130
1193
  logging.info("END: do_transition")
1131
1194
  except Exception as e:
1132
1195
  traceback.print_exc()
1133
1196
  logging.info(f"------------RESET---------------")
1134
1197
  self.reset()
1135
- self.notify("STOP")
1198
+ self.notify(session['session_id'], "STOP")
1136
1199
  return owner, DialogState.START, "Lo lamento, no puedo responder en este momento", owner
1137
1200
 
1138
1201
  def set_knowledge(self, knowledge) -> str:
@@ -13,6 +13,8 @@
13
13
  # Define resources
14
14
  # --------------------------------------------------------
15
15
 
16
+ import json
17
+ import logging
16
18
  import traceback
17
19
  from openai import AzureOpenAI
18
20
  from abc import ABC, abstractmethod
@@ -20,7 +22,7 @@ from azure.ai.projects import AIProjectClient
20
22
  from azure.identity import DefaultAzureCredential
21
23
  from azure.ai.inference import ChatCompletionsClient
22
24
  from azure.core.credentials import AzureKeyCredential
23
-
25
+ from azure.core.exceptions import HttpResponseError
24
26
  import time
25
27
  from openai import AzureOpenAI, RateLimitError, APIStatusError
26
28
  from tenacity import (
@@ -135,13 +137,46 @@ class AzureInference(AIService):
135
137
  credential=AzureKeyCredential(config['AZURE_INFERENCE_SDK_KEY'])
136
138
  )
137
139
 
138
- def generate(self, work_memory) -> str:
139
- response = self.model.complete(
140
- messages= work_memory,
141
- model =self.model_conf['DEPLOYMENT_NAME'],
142
- max_tokens=self.model_conf['MAX_TOKENS']
143
- )
144
- return response.choices[0].message.content
140
+ def generate(self, work_memory, max_tokens=2000, temperature=0, top_p=0.9) -> str:
141
+ try:
142
+ response = self.model.complete(
143
+ messages= work_memory,
144
+ model =self.model_conf['DEPLOYMENT_NAME'],
145
+ max_tokens=self.model_conf['MAX_TOKENS']
146
+ )
147
+ return response.choices[0].message.content
148
+ except Exception as e:
149
+ # Maneja otros errores
150
+ trace_err = traceback.format_exc()
151
+ err = str(e) + " - " + trace_err
152
+ print(f"Error en la respuesta de Azure: {err}")
153
+ if self.model_conf['SUBSTITUDE_DEPLOYMENT_NAME'] == "Llama-3.3-70B-Instruct":
154
+ print("\n\n\n")
155
+ print("----------------------------------------")
156
+ print("Entra a jugar el sustituto")
157
+ try:
158
+ logging.info("\n\n\n.............................................")
159
+ logging.info("\n%s", json.dumps(work_memory, indent=4))
160
+ logging.info("........................................\n\n\n")
161
+
162
+ response = self.model.complete(
163
+ messages= work_memory,
164
+ model =self.model_conf['SUBSTITUDE_DEPLOYMENT_NAME'],
165
+ max_tokens=self.model_conf['MAX_TOKENS']
166
+ )
167
+ print("----------------------------------------")
168
+ print("\n\n\n")
169
+
170
+ return response.choices[0].message.content
171
+ except Exception as e2:
172
+ trace_err2 = traceback.format_exc()
173
+ err2 = str(e2) + " - " + trace_err2
174
+ print(f"Error en la respuesta de Azure: {err2}")
175
+ print("----------------------------------------")
176
+ print("\n\n\n")
177
+
178
+ raise e2
179
+
145
180
 
146
181
  # Función auxiliar para determinar la espera basada en el error
147
182
  def wait_strategy_for_rate_limit(retry_state):
@@ -253,7 +253,9 @@ class Delegate(Action):
253
253
  'gateway': data['gateway'],
254
254
  'dtoList': []
255
255
  }
256
+ logging.info(f"[Delegate][{self.agent.id}]: Assign to agent {ag}")
256
257
  self.adm.send_event(ag, 'task', data['dto'])
258
+ logging.info(f"[Delegate][{self.agent.id}]: Agent {ag} assigned")
257
259
  if 'timeout' in self.agent.state:
258
260
  self.active_timeout(ag, self.agent.state['timeout'])
259
261
  else:
@@ -293,7 +295,8 @@ class ResponseAction(Action):
293
295
  """ Execute
294
296
  @param data: Data
295
297
  """
296
- logging.info(f"[ResponseAction][{self.agent.id}]: Response: {data}")
298
+ #@TODO: Check if the data is valid
299
+ #logging.info(f"[ResponseAction][{self.agent.id}]: Obtiene respuesta")
297
300
  if data['source'] in self.agent.get_request_dict():
298
301
  request = self.agent.get_request_dict()[data['source']]
299
302