pbesa 4.0.34__tar.gz → 4.0.36__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 (125) hide show
  1. {pbesa-4.0.34 → pbesa-4.0.36}/PKG-INFO +1 -1
  2. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/__init__.py +2 -1
  3. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_casos.py +1 -1
  4. pbesa-4.0.36/pbesa/celulas/celula_parafraseo.py +81 -0
  5. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/cognitive.py +64 -130
  6. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/models.py +8 -8
  7. pbesa-4.0.36/pbesa/simulator/__init__.py +1 -0
  8. pbesa-4.0.36/pbesa/simulator/dialog_simulator.py +94 -0
  9. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/dispatcher_team.py +3 -2
  10. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa.egg-info/PKG-INFO +1 -1
  11. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa.egg-info/SOURCES.txt +2 -0
  12. {pbesa-4.0.34 → pbesa-4.0.36}/setup.py +1 -1
  13. pbesa-4.0.34/pbesa/celulas/celula_parafraseo.py +0 -56
  14. {pbesa-4.0.34 → pbesa-4.0.36}/.gitignore +0 -0
  15. {pbesa-4.0.34 → pbesa-4.0.36}/LICENSE +0 -0
  16. {pbesa-4.0.34 → pbesa-4.0.36}/LICENSE.txt +0 -0
  17. {pbesa-4.0.34 → pbesa-4.0.36}/MANIFEST +0 -0
  18. {pbesa-4.0.34 → pbesa-4.0.36}/README.md +0 -0
  19. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/db.sqlite3 +0 -0
  20. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/__init__.py +0 -0
  21. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/__pycache__/__init__.cpython-36.pyc +0 -0
  22. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/__pycache__/pbesa.cpython-36.pyc +0 -0
  23. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/__pycache__/settings.cpython-36.pyc +0 -0
  24. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/__pycache__/urls.cpython-36.pyc +0 -0
  25. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/__pycache__/wsgi.cpython-36.pyc +0 -0
  26. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/asgi.py +0 -0
  27. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/pbesa.py +0 -0
  28. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/settings.py +0 -0
  29. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/urls.py +0 -0
  30. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/helloworld/wsgi.py +0 -0
  31. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/manage.py +0 -0
  32. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__init__.py +0 -0
  33. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__pycache__/__init__.cpython-36.pyc +0 -0
  34. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__pycache__/admin.cpython-36.pyc +0 -0
  35. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__pycache__/apps.cpython-36.pyc +0 -0
  36. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__pycache__/models.cpython-36.pyc +0 -0
  37. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__pycache__/urls.cpython-36.pyc +0 -0
  38. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/__pycache__/views.cpython-36.pyc +0 -0
  39. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/admin.py +0 -0
  40. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/apps.py +0 -0
  41. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/controller/__pycache__/translatecontroller.cpython-36.pyc +0 -0
  42. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/controller/__pycache__/translatedelegate.cpython-36.pyc +0 -0
  43. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/controller/__pycache__/translateresponse.cpython-36.pyc +0 -0
  44. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/controller/translatecontroller.py +0 -0
  45. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/controller/translatedelegate.py +0 -0
  46. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/controller/translateresponse.py +0 -0
  47. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/worker/__pycache__/translatetask.cpython-36.pyc +0 -0
  48. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/worker/__pycache__/workeragent.cpython-36.pyc +0 -0
  49. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/worker/translatetask.py +0 -0
  50. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/mas/worker/workeragent.py +0 -0
  51. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/migrations/__init__.py +0 -0
  52. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/migrations/__pycache__/__init__.cpython-36.pyc +0 -0
  53. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/models.py +0 -0
  54. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/tests.py +0 -0
  55. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/urls.py +0 -0
  56. {pbesa-4.0.34 → pbesa-4.0.36}/examples/django/helloworld/translate/views.py +0 -0
  57. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/__pycache__/countercontroller.cpython-36.pyc +0 -0
  58. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/__pycache__/counterdelegate.cpython-36.pyc +0 -0
  59. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/__pycache__/counterresponse.cpython-36.pyc +0 -0
  60. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/__pycache__/translatecontroller.cpython-36.pyc +0 -0
  61. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/__pycache__/translatedelegate.cpython-36.pyc +0 -0
  62. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/__pycache__/translateresponse.cpython-36.pyc +0 -0
  63. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/countercontroller.py +0 -0
  64. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/counterdelegate.py +0 -0
  65. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/controller/counterresponse.py +0 -0
  66. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/worker/__pycache__/counteragent.cpython-36.pyc +0 -0
  67. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/worker/__pycache__/countertask.cpython-36.pyc +0 -0
  68. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/worker/__pycache__/translatetask.cpython-36.pyc +0 -0
  69. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/worker/__pycache__/workeragent.cpython-36.pyc +0 -0
  70. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/worker/counteragent.py +0 -0
  71. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/mas/worker/countertask.py +0 -0
  72. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/remote_a.py +0 -0
  73. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/remote_b.py +0 -0
  74. {pbesa-4.0.34 → pbesa-4.0.36}/examples/remote/remote_c.py +0 -0
  75. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/__init__.py +0 -0
  76. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_consultas.py +0 -0
  77. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_conversador.py +0 -0
  78. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_cuestionador.py +0 -0
  79. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_datos_identificables.py +0 -0
  80. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_evaluador.py +0 -0
  81. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_expertos.py +0 -0
  82. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_extraccion.py +0 -0
  83. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_generar_caso.py +0 -0
  84. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_generar_documento.py +0 -0
  85. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_instruccion.py +0 -0
  86. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_pertinencia.py +0 -0
  87. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_preguntas.py +0 -0
  88. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_respuesta.py +0 -0
  89. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/celula_saludos.py +0 -0
  90. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/data_extraction_cel.py +0 -0
  91. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/celulas/web.py +0 -0
  92. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/__init__.py +0 -0
  93. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/adapter.py +0 -0
  94. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/agent.py +0 -0
  95. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/io/__init__.py +0 -0
  96. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/io/system_file.py +0 -0
  97. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/io/tcp_server.py +0 -0
  98. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/res/__init__.py +0 -0
  99. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/res/__pycache__/__init__.cpython-36.pyc +0 -0
  100. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/res/__pycache__/__init__.cpython-37.pyc +0 -0
  101. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/res/__pycache__/__init__.cpython-38.pyc +0 -0
  102. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/res/__pycache__/__init__.cpython-39.pyc +0 -0
  103. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/res/conf.json +0 -0
  104. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/util.py +0 -0
  105. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/kernel/world.py +0 -0
  106. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/mas.py +0 -0
  107. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/remote/__init__.py +0 -0
  108. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/remote/adm_listener.py +0 -0
  109. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/remote/adm_listener_handler.py +0 -0
  110. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/remote/exceptions.py +0 -0
  111. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/remote/remote_adm.py +0 -0
  112. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/remote/remote_adm_handler.py +0 -0
  113. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/__init__.py +0 -0
  114. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/collaborative_team.py +0 -0
  115. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/delegator.py +0 -0
  116. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/delegator_team.py +0 -0
  117. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/dialog.py +0 -0
  118. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/prompts.py +0 -0
  119. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/selected_dispatcher_team.py +0 -0
  120. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/templates.py +0 -0
  121. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa/social/worker.py +0 -0
  122. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa.egg-info/dependency_links.txt +0 -0
  123. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa.egg-info/requires.txt +0 -0
  124. {pbesa-4.0.34 → pbesa-4.0.36}/pbesa.egg-info/top_level.txt +0 -0
  125. {pbesa-4.0.34 → pbesa-4.0.36}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pbesa
3
- Version: 4.0.34
3
+ Version: 4.0.36
4
4
  License-File: LICENSE
5
5
  License-File: LICENSE.txt
6
6
  Requires-Dist: pymongo>=4.6.3
@@ -3,4 +3,5 @@ from .social import *
3
3
  from .remote import *
4
4
  from .cognitive import *
5
5
  from .models import *
6
- from .celulas import *
6
+ from .celulas import *
7
+ from .simulator import *
@@ -38,7 +38,7 @@ Responde únicamente con:
38
38
  """
39
39
 
40
40
  # Efectua la inferencia del modelo.
41
- def derive(service, text, max_tkns=4096) -> any:
41
+ def derive(service, text, max_tkns=2000) -> any:
42
42
  try:
43
43
  logging.info(f"Procesando: {text}")
44
44
  tmp_work_memory = []
@@ -0,0 +1,81 @@
1
+ import logging
2
+
3
+ FRAMEWORK = """
4
+ Justifacil articula un marco único de preguntas para diecisiete clases de autoridades colombianas, agrupadas por dominio y competencia, bajo el Código General del Proceso (Ley 1564 de 2012). DIMAR salvaguarda la navegación, ambiente y seguridad marítima; DNDA administra el régimen de derecho de autor; ICA garantiza sanidad e inocuidad agropecuaria. La SFC regula solvencia, transparencia y servicios del sistema financiero, banca, inversión e innovación. La SIC despliega tres frentes: competencia desleal, protección al consumidor y propiedad industrial, vigilando mercados, derechos de marca e intereses de usuarios. Supersalud cubre siete ámbitos—cobertura de servicios, devoluciones, conflictos entre entidades, libre elección, multiafiliación, reconocimiento económico y sostenibilidad—asegurando acceso, flujo financiero y derechos de los pacientes. Supersociedades abarca liquidación, reorganización, validación judicial y conflictos mercantiles para preservar empresas y créditos. Este resumen nutre las secciones de glosario, preguntas frecuentes y observatorio de justicia, permitiendo al agente cognitivo responder con celeridad sobre licencias, registros, sanciones, garantías, reembolsos, procesos concursales complejos y demás trámites digitales que tramita Justifacil.
5
+ """.strip()
6
+
7
+ SYSTEM_PROMPT = """
8
+ Dado el siguiente **Marco normativo y Competencial**, el **Conocimiento** disponible
9
+ y la **Consulta de usuario**, responde en lenguaje natural, con cortesía y sin tutear.
10
+
11
+ **Marco normativo y Competencial**
12
+ %s
13
+
14
+ **Conocimiento**
15
+ %s
16
+
17
+ **Consulta de usuario**
18
+ %s
19
+
20
+ - Proceso de respuesta
21
+ 1. **Prioridad de fuentes**
22
+ a. Si el Conocimiento responde plenamente la consulta, úsalo como base principal.
23
+ b. Si la consulta no está cubierta por el Conocimiento, fundamenta la respuesta
24
+ únicamente en el Marco normativo y Competencial.
25
+ c. Si la consulta no tiene relación con ninguno de los dos, responde solo:
26
+ «Lo lamento, la consulta está fuera del alcance de mis competencias en Justifacil».
27
+
28
+ 2. **Reglas de cobertura**
29
+ - Limita el contenido a trámites, funciones y competencias de las entidades
30
+ incluidas en el Marco normativo y Competencial.
31
+ - No inventes información ni extrapoles más allá de las fuentes proporcionadas.
32
+ - Tu respuesta debe ser clara, concisa y relevante para la consulta del usuario.
33
+ - Evita agregar información que no esté en el 'Conocimiento' o sea pertinente al 'Marco normativo y Competencial'.
34
+ - Evita agregar explicaciones innecesarias o adicionales.
35
+ - Solo limitate a responder la consulta parafraseando el 'Conocimiento' proporcionado.
36
+
37
+ 3. **Estilo y tono**
38
+ - Persiste en trato formal (usted).
39
+ - Sé claro, conciso y amable; evita explicaciones innecesarias.
40
+ - No incluyas información ajena al Conocimiento o al Marco normativo.
41
+ - Concluye siempre invitando al usuario a realizar nuevas consultas.
42
+
43
+ - Ejemplo admisible
44
+ Usuario: «Quiero saber cómo iniciar un proceso por actos de competencia desleal»
45
+ Asistente: «Para iniciar un proceso por actos de competencia desleal se sigue la Ley 256
46
+ de 1996…»
47
+
48
+ - Ejemplo fuera de alcance
49
+ Usuario: «¿Cómo puedo sacar la visa?»
50
+ Asistente: «Lo lamento, la consulta está fuera del alcance de mis competencias en Justifacil».
51
+
52
+ - Ejemplo fuera de alcance
53
+ Usuario: «Un extaterrestre copio mi marca ¿Cómo puedo frente a la SIC demandar al extraterres?»
54
+ Asistente: «Lo lamento, la consulta está fuera del alcance de mis competencias en Justifacil».
55
+
56
+ """
57
+
58
+ USER_PROMPT = """
59
+
60
+ Respuesta:
61
+ """
62
+
63
+ # Efectua la inferencia del modelo.
64
+ def derive(service, conocimiento, consulta, max_tkns=2000) -> any:
65
+ try:
66
+ tmp_work_memory = []
67
+ prompt = SYSTEM_PROMPT % (FRAMEWORK, conocimiento, consulta)
68
+ tmp_work_memory.append({"role": "system", "content": prompt})
69
+ prompt = USER_PROMPT
70
+ tmp_work_memory.append({"role": "user", "content": prompt})
71
+ res = service.generate(tmp_work_memory, max_tokens=max_tkns)
72
+ logging.info(f"\n\n\nProcesando:\Conocimiento: {conocimiento}\nConsulta: {consulta}")
73
+ logging.info(f"Respuesta: {res}")
74
+ if not res or res == "":
75
+ res = consulta
76
+ logging.warning(f"No obtener una respuesta.")
77
+ return res
78
+ except Exception as e:
79
+ logging.error(f"Error al procesar: {consulta}")
80
+ logging.error(e)
81
+ return None
@@ -981,6 +981,12 @@ class Dialog(ABC):
981
981
  res = query
982
982
  else:
983
983
  ambiguedad = True
984
+ per_res = celula_pertinencia.derive(self.__ai_service, query, max_tkns=10)
985
+ if per_res and not per_res == "":
986
+ if "ABSURDO" in per_res:
987
+ dicriminador = None
988
+ res = msg
989
+ ambiguedad = False
984
990
 
985
991
  if ambiguedad:
986
992
  logging.info("[Stage-1]: Respuesta con ambiguedad")
@@ -1665,88 +1671,31 @@ class SpecialDispatch():
1665
1671
  Response.
1666
1672
  @param data Event data
1667
1673
  """
1668
- response = None
1669
- if data and not data['dto']['session']['team'] == "Funcionalidades":
1670
- logging.info("Despachando por descripcion...")
1671
- options = ""
1672
- cont = 1
1673
- agent_options = {}
1674
- for agent, item in self.__options_dict.items():
1675
- agent_options[cont] = agent
1676
- options += f"{cont}) {item}\n"
1677
- cont += 1
1678
- query = data['dto']['text'] if data and 'dto' in data and data['dto']['text'] is not None else ''
1679
- prompt = CLASSIFICATION_PROMPT % options
1680
- logging.info(f"Query: {query},\n Options:\n{options}")
1681
- self.__meta_work_memory.append({"role": "system", "content": prompt})
1682
-
1683
-
1684
- user_prompt = f"""
1685
- Texto: "%s"
1686
-
1687
- Respuesta:
1688
- """ % query
1689
- self.__meta_work_memory.append({"role": "user", "content": user_prompt})
1690
-
1691
- res = self.__ai_service.generate(self.__meta_work_memory, max_tokens=10)
1692
- logging.info(f"Thought: {res}")
1693
- self.__meta_work_memory = []
1694
- res = self.get_text(res)
1695
- select_agent = None
1696
- compare = re.findall(r'\d+', res)
1697
- print(f"Compare: {compare}")
1698
- if len(compare) > 0:
1699
- compare = compare[0]
1700
- else:
1701
- compare = res
1702
- compare = compare.strip()
1703
- print(f"Compare: {compare}")
1704
- for option in range(1, cont+1):
1705
- print(f"Option: {option} - Compare: {compare}")
1706
- if str(option) == compare:
1707
- select_agent = agent_options[option]
1708
- logging.info(f"Descripcion del agente seleccionado: {select_agent}")
1709
- break
1710
- if not select_agent:
1711
- logging.info("=> No se seleccionó ningun agente")
1712
- return select_agent, response
1713
- else:
1714
- logging.info("Despachando por descripcion...")
1715
- options = ""
1716
- cont = 1
1717
-
1718
- selection_options = {}
1719
-
1720
- agent_options = {}
1721
- for agent, item in self.__options_dict.items():
1722
- agent_options[cont] = agent
1723
- options += f"{cont}) {item}\n"
1724
- cont += 1
1725
- selection_options[agent] = 0
1726
-
1727
- query = data['dto']['text'] if data and 'dto' in data and data['dto']['text'] is not None else ''
1728
- prompt = CLASSIFICATION_PROMPT % options
1729
- logging.info(f"Query: {query},\n Options:\n{options}")
1730
- self.__meta_work_memory.append({"role": "system", "content": prompt})
1731
-
1732
-
1733
- user_prompt = f"""
1734
- Texto: "%s"
1735
-
1736
- Respuesta:
1737
- """ % query
1738
- self.__meta_work_memory.append({"role": "user", "content": user_prompt})
1739
-
1740
- self.kusto_open()
1741
-
1742
- attemps = 1
1743
- exit = False
1744
- while attemps <= 3 and not exit:
1745
- logging.info(f"Intento de selección de agente: {attemps}")
1746
-
1674
+ try:
1675
+ response = None
1676
+ if data and not data['dto']['session']['team'] == "Funcionalidades":
1677
+ logging.info("Despachando por descripcion...")
1678
+ options = ""
1679
+ cont = 1
1680
+ agent_options = {}
1681
+ for agent, item in self.__options_dict.items():
1682
+ agent_options[cont] = agent
1683
+ options += f"{cont}) {item}\n"
1684
+ cont += 1
1685
+ query = data['dto']['text'] if data and 'dto' in data and data['dto']['text'] is not None else ''
1686
+ prompt = CLASSIFICATION_PROMPT % options
1687
+ logging.info(f"Query: {query},\n Options:\n{options}")
1688
+ self.__meta_work_memory.append({"role": "system", "content": prompt})
1689
+ user_prompt = f"""
1690
+ Texto: "%s"
1691
+
1692
+ Respuesta:
1693
+ """ % query
1694
+ self.__meta_work_memory.append({"role": "user", "content": user_prompt})
1695
+
1747
1696
  res = self.__ai_service.generate(self.__meta_work_memory, max_tokens=10)
1748
1697
  logging.info(f"Thought: {res}")
1749
-
1698
+ self.__meta_work_memory = []
1750
1699
  res = self.get_text(res)
1751
1700
  select_agent = None
1752
1701
  compare = re.findall(r'\d+', res)
@@ -1765,58 +1714,43 @@ class SpecialDispatch():
1765
1714
  break
1766
1715
  if not select_agent:
1767
1716
  logging.info("=> No se seleccionó ningun agente")
1768
-
1717
+ return select_agent, response
1718
+ else:
1719
+ logging.info("Despachando por indice...")
1720
+ query = data['dto']['text'] if data and 'dto' in data and data['dto']['text'] is not None else ''
1721
+ options = ""
1722
+ cont = 1
1723
+
1724
+ # Considera las opciones
1725
+ agent_options = []
1726
+ for agent, _ in self.__options_dict.items():
1727
+ key = "-".join(agent.split("-")[0:-1])
1728
+ if not key in agent_options:
1729
+ agent_options.append(key)
1730
+
1731
+ # Efecua consulta al indice
1732
+ self.kusto_open()
1769
1733
  major_id, response, score = self.retrieval(query)
1770
- if 'glosario' in major_id.lower():
1771
- major_id = 'glosario'
1772
- elif 'inicial' in major_id.lower():
1773
- major_id = 'portal'
1774
- else:
1775
- major_id_split = major_id.split("_")
1776
- major_id = major_id_split[0] if len(major_id_split) > 0 else major_id
1777
- major_id_split = major_id.split("-")
1778
- major_id = major_id_split[1] if len(major_id_split) > 0 else major_id
1779
-
1780
- compare_llm = 0
1781
- compare_index = 0
1782
- idex_result = None
1783
-
1784
- # Check if the selected agent is in the retrieval response
1785
- if major_id and major_id in select_agent:
1786
- logging.info(f"Se seleccionó el agente: {select_agent} con score: {score}")
1787
- exit = True
1788
- continue
1789
- else:
1790
- for ag in selection_options:
1791
- if select_agent and select_agent in ag:
1792
- selection_options[ag] += 1
1793
- compare_llm += 1
1794
- if major_id and major_id in ag:
1795
- selection_options[ag] += 1
1796
- compare_index += 1
1797
- idex_result = ag
1798
-
1799
- attemps += 1
1800
-
1801
- if attemps > 3:
1802
- logging.info("No se pudo seleccionar un agente, identificando el agente con mayor score...")
1734
+ self.kusto_close()
1735
+ logging.info(f"Major ID: {major_id}, Response: {response}, Score: {score}")
1803
1736
 
1804
- if compare_llm == compare_index:
1805
- logging.warning("Dando prioridad al resultado del indice")
1806
- select_agent = idex_result
1737
+ # Obtiene el tipo de agente
1738
+ select_agent = None
1739
+ if major_id:
1740
+ major_id = major_id.split("_")[0]
1741
+ for ag in agent_options:
1742
+ if major_id in ag:
1743
+ select_agent = ag
1744
+ break
1807
1745
  else:
1808
- logging.info("Evaluando los scores de los agentes...")
1809
- major_id = ""
1810
- max_score = 0
1811
- for ag, score in selection_options.items():
1812
- if score > max_score:
1813
- max_score = score
1814
- major_id = ag
1815
- if major_id:
1816
- select_agent = major_id
1817
- logging.info(f"Se seleccionó el agente: {select_agent} con score: {max_score}")
1818
-
1819
- self.kusto_close()
1746
+ logging.warning("No se encontró un agente asociado al query")
1747
+
1748
+ # Si no se encontró un agente, se retorna None
1749
+ self.__meta_work_memory = []
1750
+ self.major_id = None
1751
+ return select_agent, response
1752
+ except Exception as e:
1753
+ logging.error(f"Error en el despacho especial: {e}")
1820
1754
  self.__meta_work_memory = []
1821
1755
  self.major_id = None
1822
- return select_agent, response
1756
+ return None, None
@@ -146,7 +146,7 @@ class AzureInference(AIService):
146
146
  response = self.model.complete(
147
147
  messages= work_memory,
148
148
  model= self.deployment,
149
- max_tokens= self.max_tokens
149
+ max_tokens= max_tokens
150
150
  )
151
151
  res = response.choices[0].message.content
152
152
  if not res or res == "" or res == "ERROR":
@@ -160,7 +160,7 @@ class AzureInference(AIService):
160
160
  err = str(e) + " - " + trace_err
161
161
  logging.info(f"Error en la respuesta de Azure: {err}")
162
162
  if again:
163
- if self.model_conf['SUBSTITUDE_DEPLOYMENT_NAME'] == "Llama-3.3-70B-Instruct":
163
+ if self.model_conf['SUBSTITUDE_2_DEPLOYMENT_NAME'].lower() == "llama-3.3-70b-instruct":
164
164
  logging.info("\n\n\n")
165
165
  logging.info("----------------------------------------")
166
166
  logging.info("Sustitudo atiendendo Llama-3.3-70B-Instruct")
@@ -170,8 +170,8 @@ class AzureInference(AIService):
170
170
  logging.info("........................................\n\n\n")
171
171
  response = self.model.complete(
172
172
  messages= work_memory,
173
- model =self.model_conf['SUBSTITUDE_DEPLOYMENT_NAME'],
174
- max_tokens=self.model_conf['MAX_TOKENS']
173
+ model =self.model_conf['SUBSTITUDE_2_DEPLOYMENT_NAME'],
174
+ max_tokens=max_tokens
175
175
  )
176
176
  logging.info("----------------------------------------")
177
177
  logging.info("\n\n\n")
@@ -182,7 +182,7 @@ class AzureInference(AIService):
182
182
  logging.info(f"Error en la respuesta de Azure: {err2}")
183
183
  logging.info("----------------------------------------")
184
184
  logging.info("\n\n\n")
185
- raise e2
185
+ return ""
186
186
  logging.error("\n\n\n****************************************")
187
187
  logging.error("No se pudo generar una respuesta válida.")
188
188
  return ""
@@ -237,7 +237,7 @@ class AzureOpenAIInference(AIService):
237
237
  # Si no se especifica Retry-After, usar backoff exponencial
238
238
  self.wait_time = 2 ** (self.wait_time // 60)
239
239
 
240
- def generate(self, work_memory, max_tokens=4096, temperature=0, top_p=0.9) -> str:
240
+ def generate(self, work_memory, max_tokens=2000, temperature=0, top_p=0.9) -> str:
241
241
  again = False
242
242
  try:
243
243
  if self.main_model_enable:
@@ -303,13 +303,13 @@ class AzureOpenAIInference(AIService):
303
303
  logging.warning("Modelo principal en espera. Intentando con el modelo de sustitución-1...")
304
304
  if self.substitude_1_model is None:
305
305
  raise ValueError("No se ha configurado un modelo de sustitución-1.")
306
- return self.substitude_1_model.generate(work_memory)
306
+ return self.substitude_1_model.generate(work_memory, max_tokens=max_tokens)
307
307
  except Exception as e:
308
308
  try:
309
309
  logging.warning("Modelo principal en espera. Intentando con el modelo de sustitución-2...")
310
310
  if self.substitude_2_model is None:
311
311
  raise ValueError("No se ha configurado un modelo de sustitución-2.")
312
- return self.substitude_2_model.generate(work_memory)
312
+ return self.substitude_2_model.generate(work_memory, max_tokens=max_tokens)
313
313
  except Exception as e2:
314
314
  trace_err = traceback.format_exc()
315
315
  err = str(e2) + " - " + trace_err
@@ -0,0 +1 @@
1
+ from .dialog_simulator import DialogSimulator
@@ -0,0 +1,94 @@
1
+ import logging
2
+
3
+ SYSTEM_PROMPT = """
4
+ Eres un **simulador de demandantes ante entes de control**.
5
+ Tu tarea es leer la **solicitud de demanda** que se te entregue y luego **responder cualquier pregunta** actuando como la persona que radicó dicha demanda.
6
+
7
+ Responde siempre en **primera persona**, manteniendo un tono respetuoso y claro.
8
+ Menciona o alude a los entes de control involucrados cuando sea pertinente (SIC – Superintendencia de Industria y Comercio, ICA – Instituto Colombiano Agropecuario, DIMAR – Dirección General Marítima, SFC – Superintendencia Financiera de Colombia, SNS – Superintendencia Nacional de Salud, entre otros).
9
+
10
+ ---
11
+
12
+ ### Criterios que debe cumplir la respuesta
13
+
14
+ 1. **Perspectiva**: primera persona singular (“yo”, “mi”).
15
+ 2. **Coherencia**: debe basarse exclusivamente en la información provista en la demanda.
16
+ 3. **Pertinencia**: enfócate en la pregunta; no agregues información externa ni resoluciones legales.
17
+ 4. **Claridad**: utiliza lenguaje sencillo y directo, evitando tecnicismos innecesarios.
18
+ 5. **Respeto**: mantén un tono formal y cortés frente a la autoridad.
19
+
20
+ **Importante**:
21
+ - Solo responde a la pregunta. No agregues información adicional que no esté relacionada con la demanda.
22
+ - Solo responde a la pregunta. No agregres explicaciones o justificaciones.
23
+ - Si te preguntan datos personales, responde con datos inventados.
24
+ - Si te preguntan datos de contacto, responde con datos inventados.
25
+ - Si te preguntan de persona jurídica, responde con datos inventados.
26
+ - Si te preguntan si deseas que te asista en la radicación de la demanda, responde que sí.
27
+
28
+ ---
29
+
30
+ ### Ejemplos
31
+
32
+ **Demanda de ejemplo**
33
+ > “Como ciudadano preocupado por la seguridad fluvial, pongo en conocimiento que una barcaza de la Empresa de Transporte Fluvial del Magdalena se encuentra navegando sin certificado de navegabilidad vigente, lo cual representa un riesgo para la vida humana y la operación segura en el río.”
34
+
35
+ | Pregunta | Respuesta esperada |
36
+ |----------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
37
+ | “¿Cuál es el principal riesgo que identificó?” | “Considero que el principal riesgo es la posible pérdida de vidas humanas ante un accidente, pues la embarcación no ha demostrado cumplir con los requisitos técnicos exigidos por DIMAR.” |
38
+ | “¿Por qué decidió acudir ante la DIMAR y no a otra entidad?” | “Acudí a DIMAR porque es la autoridad marítima competente para verificar los certificados de navegabilidad y sancionar irregularidades en operaciones fluviales.” |
39
+ | “¿Ha presentado pruebas?” | “Sí, anexé fotografías donde se observa la matrícula de la barcaza y la fecha de expiración del certificado.” |
40
+
41
+ ---
42
+ """
43
+
44
+ USER_PROMPT = """
45
+ ### Plantilla de uso
46
+
47
+ Demanda:
48
+ %s
49
+ """
50
+
51
+ class DialogSimulator(object):
52
+ """
53
+ Clase que simula un usuario demandante ante entes de control.
54
+ """
55
+
56
+ def __init__(self):
57
+ self.iteracion = 1
58
+ self.work_memory = []
59
+ self.service = None
60
+
61
+ # Efectua la inferencia del modelo.
62
+ def evaluate(self, text, max_tkns=2000, reset=False) -> any:
63
+ try:
64
+ if reset:
65
+ self.iteracion = 1
66
+ self.work_memory = []
67
+ logging.info("\n")
68
+ logging.info(f"Procesando: {text} - Iteración: {self.iteracion}")
69
+ if self.iteracion == 1:
70
+ prompt = SYSTEM_PROMPT
71
+ self.work_memory.append({"role": "system", "content": SYSTEM_PROMPT})
72
+ prompt = USER_PROMPT % text
73
+ self.work_memory.append({"role": "user", "content": prompt})
74
+ else:
75
+ self.work_memory.append({"role": "user", "content": text})
76
+ res = self.service.generate(self.work_memory, max_tkns)
77
+ self.work_memory.append({"role": "assistant", "content": res})
78
+ self.iteracion += 1
79
+ logging.info(f"Respuesta: {res}")
80
+ logging.info("\n")
81
+ if not res or res == "":
82
+ res = text
83
+ logging.warning(f"No obtener una respuesta.")
84
+ return res
85
+ except Exception as e:
86
+ logging.error(f"Error al procesar: {text}")
87
+ logging.error(e)
88
+ return None
89
+
90
+ def derive(self, text, max_tkns=2000, reset=False) -> any:
91
+ return self.evaluate(text, max_tkns=max_tkns, reset=reset)
92
+
93
+ def set_service(self, service):
94
+ self.service = service
@@ -592,7 +592,8 @@ class LLMDispatcherDelegate(Action):
592
592
  # Chec if the agent is instance of AugmentedGeneration
593
593
  if isinstance(agent_obj, Dialog):
594
594
  # Get the role
595
- if select_agent == agent_obj.id:
595
+ tipo = "-".join(agent_obj.id.split('-')[0:-1])
596
+ if select_agent == tipo:
596
597
  logging.info(f'The agent {ag} is assigned')
597
598
  self.agent.get_request_dict()[ag] = {
598
599
  'gateway': data['gateway'],
@@ -603,7 +604,7 @@ class LLMDispatcherDelegate(Action):
603
604
  self.adm.send_event(ag, 'task', data['dto'])
604
605
  self.__rewier[ag] = 0
605
606
  exit = True
606
- self.planilla[session_id] = select_agent
607
+ self.planilla[session_id] = agent_obj.id
607
608
  else:
608
609
  logging.debug('The agent does not match the role')
609
610
  self.adm.send_event(agent_obj.get_controller(), 'notify', ag)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pbesa
3
- Version: 4.0.34
3
+ Version: 4.0.36
4
4
  License-File: LICENSE
5
5
  License-File: LICENSE.txt
6
6
  Requires-Dist: pymongo>=4.6.3
@@ -109,6 +109,8 @@ pbesa/remote/adm_listener_handler.py
109
109
  pbesa/remote/exceptions.py
110
110
  pbesa/remote/remote_adm.py
111
111
  pbesa/remote/remote_adm_handler.py
112
+ pbesa/simulator/__init__.py
113
+ pbesa/simulator/dialog_simulator.py
112
114
  pbesa/social/__init__.py
113
115
  pbesa/social/collaborative_team.py
114
116
  pbesa/social/delegator.py
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
4
4
 
5
5
  setup(
6
6
  name='pbesa',
7
- version='4.0.34',
7
+ version='4.0.36',
8
8
  packages=find_packages(),
9
9
  install_requires=[
10
10
  'pymongo>=4.6.3',
@@ -1,56 +0,0 @@
1
- import logging
2
-
3
- SYSTEM_PROMPT = """
4
- Dado el siguiente 'Conocimiento' y la 'Consulta de usuario', tu tarea es responder de manera amable y en lenguaje natural.
5
-
6
- **Conocimiento:**
7
- %s
8
-
9
- **Consulta de usuario:**
10
- %s
11
-
12
- **Importante:**
13
- - Es fundamental que evites responder si la consulta del usuario no se relaciona
14
- con temas jurídicos, con Justifacil y las funciones jurisdiccionales de las siguientes entidades
15
- colombianas: SIC, DNDA, DIMAR, SNS, SFC, ICA y Supersociedades, bajo el marco
16
- legal del Código General del Proceso (Ley 1564 de 2012). Recuerda que Justifacil es
17
- un sistema de información que permite adelantar tramites de estas entidades, y como tal, tiene secciones de:
18
- glosario, preguntas frecuentes, observatorio de justicia, etc.
19
- - Siempre finaliza tu respuesta invitando al usuario a hacer más consultas.
20
-
21
- **Instrucciones:**
22
- - Evita tutear al usuario.
23
- - Si la consulta del usuario no se relaciona con temas jurídicos, con Justifacil y las funciones jurisdiccionales de las siguientes entidades, inicia la respuesta con "Lo lamento, ..."
24
- - Tu respuesta debe basarse únicamente en el 'Conocimiento' proporcionado.
25
- - Tu respuesta debe ser amable y el lenguaje natural.
26
- - Tu respuesta debe ser clara, concisa y relevante para la consulta del usuario.
27
- - Evita agregar información que no esté en el 'Conocimiento'.
28
- - Evita agregar explicaciones innecesarias o adicionales.
29
- - Solo limitate a responder la consulta parafraseando el 'Conocimiento' proporcionado.
30
-
31
- """
32
-
33
- USER_PROMPT = """
34
-
35
- Respuesta:
36
- """
37
-
38
- # Efectua la inferencia del modelo.
39
- def derive(service, conocimiento, consulta, max_tkns=2000) -> any:
40
- try:
41
- tmp_work_memory = []
42
- prompt = SYSTEM_PROMPT % (conocimiento, consulta)
43
- tmp_work_memory.append({"role": "system", "content": prompt})
44
- prompt = USER_PROMPT
45
- tmp_work_memory.append({"role": "user", "content": prompt})
46
- res = service.generate(tmp_work_memory, max_tokens=max_tkns)
47
- logging.info(f"\n\n\nProcesando:\Conocimiento: {conocimiento}\nConsulta: {consulta}")
48
- logging.info(f"Respuesta: {res}")
49
- if not res or res == "":
50
- res = consulta
51
- logging.warning(f"No obtener una respuesta.")
52
- return res
53
- except Exception as e:
54
- logging.error(f"Error al procesar: {consulta}")
55
- logging.error(e)
56
- return None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes