iatoolkit 0.59.1__py3-none-any.whl → 0.59.2__py3-none-any.whl
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.
Potentially problematic release.
This version of iatoolkit might be problematic. Click here for more details.
- iatoolkit/base_company.py +3 -1
- iatoolkit/iatoolkit.py +1 -1
- iatoolkit/repositories/models.py +1 -1
- iatoolkit/services/user_feedback_service.py +65 -26
- iatoolkit/static/js/chat_feedback.js +1 -3
- iatoolkit/views/user_feedback_api_view.py +0 -10
- {iatoolkit-0.59.1.dist-info → iatoolkit-0.59.2.dist-info}/METADATA +1 -1
- {iatoolkit-0.59.1.dist-info → iatoolkit-0.59.2.dist-info}/RECORD +10 -10
- {iatoolkit-0.59.1.dist-info → iatoolkit-0.59.2.dist-info}/WHEEL +0 -0
- {iatoolkit-0.59.1.dist-info → iatoolkit-0.59.2.dist-info}/top_level.txt +0 -0
iatoolkit/base_company.py
CHANGED
|
@@ -29,11 +29,13 @@ class BaseCompany(ABC):
|
|
|
29
29
|
def _create_company(self,
|
|
30
30
|
short_name: str,
|
|
31
31
|
name: str,
|
|
32
|
+
parameters: dict | None = None,
|
|
32
33
|
branding: dict | None = None,
|
|
33
|
-
onboarding_cards: dict | None = None
|
|
34
|
+
onboarding_cards: dict | None = None,
|
|
34
35
|
) -> Company:
|
|
35
36
|
company_obj = Company(short_name=short_name,
|
|
36
37
|
name=name,
|
|
38
|
+
parameters=parameters,
|
|
37
39
|
branding=branding,
|
|
38
40
|
onboarding_cards=onboarding_cards)
|
|
39
41
|
self.company = self.profile_repo.create_company(company_obj)
|
iatoolkit/iatoolkit.py
CHANGED
|
@@ -19,7 +19,7 @@ from werkzeug.middleware.proxy_fix import ProxyFix
|
|
|
19
19
|
from injector import Binder, singleton, Injector
|
|
20
20
|
from importlib.metadata import version as _pkg_version, PackageNotFoundError
|
|
21
21
|
|
|
22
|
-
IATOOLKIT_VERSION = "0.59.
|
|
22
|
+
IATOOLKIT_VERSION = "0.59.2"
|
|
23
23
|
|
|
24
24
|
# global variable for the unique instance of IAToolkit
|
|
25
25
|
_iatoolkit_instance: Optional['IAToolkit'] = None
|
iatoolkit/repositories/models.py
CHANGED
|
@@ -60,7 +60,7 @@ class Company(Base):
|
|
|
60
60
|
|
|
61
61
|
branding = Column(JSON, nullable=True)
|
|
62
62
|
onboarding_cards = Column(JSON, nullable=True)
|
|
63
|
-
parameters = Column(JSON, nullable=True
|
|
63
|
+
parameters = Column(JSON, nullable=True)
|
|
64
64
|
created_at = Column(DateTime, default=datetime.now)
|
|
65
65
|
allow_jwt = Column(Boolean, default=True, nullable=True)
|
|
66
66
|
|
|
@@ -3,62 +3,101 @@
|
|
|
3
3
|
#
|
|
4
4
|
# IAToolkit is open source software.
|
|
5
5
|
|
|
6
|
-
from iatoolkit.repositories.models import UserFeedback
|
|
6
|
+
from iatoolkit.repositories.models import UserFeedback, Company
|
|
7
7
|
from injector import inject
|
|
8
8
|
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
9
9
|
from iatoolkit.infra.google_chat_app import GoogleChatApp
|
|
10
|
+
from iatoolkit.infra.mail_app import MailApp # <-- 1. Importar MailApp
|
|
10
11
|
import logging
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class UserFeedbackService:
|
|
14
15
|
@inject
|
|
15
|
-
def __init__(self,
|
|
16
|
+
def __init__(self,
|
|
17
|
+
profile_repo: ProfileRepo,
|
|
18
|
+
google_chat_app: GoogleChatApp,
|
|
19
|
+
mail_app: MailApp):
|
|
16
20
|
self.profile_repo = profile_repo
|
|
17
21
|
self.google_chat_app = google_chat_app
|
|
22
|
+
self.mail_app = mail_app
|
|
23
|
+
|
|
24
|
+
def _send_google_chat_notification(self, space_name: str, message_text: str):
|
|
25
|
+
"""Envía una notificación de feedback a un espacio de Google Chat."""
|
|
26
|
+
try:
|
|
27
|
+
chat_data = {
|
|
28
|
+
"type": "MESSAGE_TRIGGER",
|
|
29
|
+
"space": {"name": space_name},
|
|
30
|
+
"message": {"text": message_text}
|
|
31
|
+
}
|
|
32
|
+
chat_result = self.google_chat_app.send_message(message_data=chat_data)
|
|
33
|
+
if not chat_result.get('success'):
|
|
34
|
+
logging.warning(f"Error al enviar notificación a Google Chat: {chat_result.get('message')}")
|
|
35
|
+
except Exception as e:
|
|
36
|
+
logging.exception(f"Fallo inesperado al enviar notificación a Google Chat: {e}")
|
|
37
|
+
|
|
38
|
+
def _send_email_notification(self, destination_email: str, company_name: str, message_text: str):
|
|
39
|
+
"""Envía una notificación de feedback por correo electrónico."""
|
|
40
|
+
try:
|
|
41
|
+
subject = f"Nuevo Feedback de {company_name}"
|
|
42
|
+
# Convertir el texto plano a un HTML simple para mantener los saltos de línea
|
|
43
|
+
html_body = message_text.replace('\n', '<br>')
|
|
44
|
+
self.mail_app.send_email(to=destination_email, subject=subject, body=html_body)
|
|
45
|
+
except Exception as e:
|
|
46
|
+
logging.exception(f"Fallo inesperado al enviar email de feedback: {e}")
|
|
47
|
+
|
|
48
|
+
def _handle_notification(self, company: Company, message_text: str):
|
|
49
|
+
"""Lee la configuración de la empresa y envía la notificación al canal correspondiente."""
|
|
50
|
+
feedback_params = company.parameters.get('user_feedback')
|
|
51
|
+
if not isinstance(feedback_params, dict):
|
|
52
|
+
logging.warning(f"No se encontró configuración de 'user_feedback' para la empresa {company.short_name}.")
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
# get channel and destination
|
|
56
|
+
channel = feedback_params.get('channel')
|
|
57
|
+
destination = feedback_params.get('destination')
|
|
58
|
+
if not channel or not destination:
|
|
59
|
+
logging.warning(f"Configuración 'user_feedback' incompleta para {company.short_name}. Faltan 'channel' o 'destination'.")
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
if channel == 'google_chat':
|
|
63
|
+
self._send_google_chat_notification(space_name=destination, message_text=message_text)
|
|
64
|
+
elif channel == 'email':
|
|
65
|
+
self._send_email_notification(destination_email=destination, company_name=company.short_name, message_text=message_text)
|
|
66
|
+
else:
|
|
67
|
+
logging.warning(f"Canal de feedback '{channel}' no reconocido para la empresa {company.short_name}.")
|
|
18
68
|
|
|
19
69
|
def new_feedback(self,
|
|
20
70
|
company_short_name: str,
|
|
21
71
|
message: str,
|
|
22
72
|
user_identifier: str,
|
|
23
|
-
space: str = None,
|
|
24
|
-
type: str = None,
|
|
25
73
|
rating: int = None) -> dict:
|
|
26
74
|
try:
|
|
27
|
-
#
|
|
75
|
+
# 1. Validar empresa
|
|
28
76
|
company = self.profile_repo.get_company_by_short_name(company_short_name)
|
|
29
77
|
if not company:
|
|
30
78
|
return {'error': f'No existe la empresa: {company_short_name}'}
|
|
31
79
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"space": {
|
|
39
|
-
"name": space
|
|
40
|
-
},
|
|
41
|
-
"message": {
|
|
42
|
-
"text": chat_message
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
chat_result = self.google_chat_app.send_message(message_data=chat_data)
|
|
47
|
-
if not chat_result.get('success'):
|
|
48
|
-
logging.warning(f"Error al enviar notificación a Google Chat: {chat_result.get('message')}")
|
|
80
|
+
# 2. Enviar notificación según la configuración de la empresa
|
|
81
|
+
notification_text = (f"*Nuevo feedback de {company_short_name}*:\n"
|
|
82
|
+
f"*Usuario:* {user_identifier}\n"
|
|
83
|
+
f"*Mensaje:* {message}\n"
|
|
84
|
+
f"*Calificación:* {rating if rating is not None else 'N/A'}")
|
|
85
|
+
self._handle_notification(company, notification_text)
|
|
49
86
|
|
|
50
|
-
#
|
|
51
|
-
|
|
87
|
+
# 3. Guardar el feedback en la base de datos (independientemente del éxito de la notificación)
|
|
88
|
+
new_feedback_obj = UserFeedback(
|
|
52
89
|
company_id=company.id,
|
|
53
90
|
message=message,
|
|
54
91
|
user_identifier=user_identifier,
|
|
55
92
|
rating=rating
|
|
56
93
|
)
|
|
57
|
-
|
|
58
|
-
if not
|
|
94
|
+
saved_feedback = self.profile_repo.save_feedback(new_feedback_obj)
|
|
95
|
+
if not saved_feedback:
|
|
96
|
+
logging.error(f"No se pudo guardar el feedback para el usuario {user_identifier} en la empresa {company_short_name}")
|
|
59
97
|
return {'error': 'No se pudo guardar el feedback'}
|
|
60
98
|
|
|
61
99
|
return {'message': 'Feedback guardado correctamente'}
|
|
62
100
|
|
|
63
101
|
except Exception as e:
|
|
102
|
+
logging.exception(f"Error crítico en el servicio de feedback: {e}")
|
|
64
103
|
return {'error': str(e)}
|
|
@@ -101,12 +101,10 @@ const sendFeedback = async function(message) {
|
|
|
101
101
|
"user_identifier": window.user_identifier,
|
|
102
102
|
"message": message,
|
|
103
103
|
"rating": activeStars,
|
|
104
|
-
"space": "spaces/AAQAupQldd4", // Este valor podría necesitar ser dinámico
|
|
105
|
-
"type": "MESSAGE_TRIGGER"
|
|
106
104
|
};
|
|
107
105
|
try {
|
|
108
106
|
// Asumiendo que callLLMAPI está definido globalmente en otro archivo (ej. chat_main.js)
|
|
109
|
-
const responseData = await callToolkit('/feedback', data, "POST");
|
|
107
|
+
const responseData = await callToolkit('/api/feedback', data, "POST");
|
|
110
108
|
return responseData;
|
|
111
109
|
} catch (error) {
|
|
112
110
|
console.error("Error al enviar feedback:", error);
|
|
@@ -37,14 +37,6 @@ class UserFeedbackApiView(MethodView):
|
|
|
37
37
|
if not message:
|
|
38
38
|
return jsonify({"error_message": "Falta el mensaje de feedback"}), 400
|
|
39
39
|
|
|
40
|
-
space = data.get("space")
|
|
41
|
-
if not space:
|
|
42
|
-
return jsonify({"error_message": "Falta el espacio de Google Chat"}), 400
|
|
43
|
-
|
|
44
|
-
type = data.get("type")
|
|
45
|
-
if not type:
|
|
46
|
-
return jsonify({"error_message": "Falta el tipo de feedback"}), 400
|
|
47
|
-
|
|
48
40
|
rating = data.get("rating")
|
|
49
41
|
if not rating:
|
|
50
42
|
return jsonify({"error_message": "Falta la calificación"}), 400
|
|
@@ -54,8 +46,6 @@ class UserFeedbackApiView(MethodView):
|
|
|
54
46
|
company_short_name=company_short_name,
|
|
55
47
|
message=message,
|
|
56
48
|
user_identifier=user_identifier,
|
|
57
|
-
space=space,
|
|
58
|
-
type=type,
|
|
59
49
|
rating=rating
|
|
60
50
|
)
|
|
61
51
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
iatoolkit/__init__.py,sha256=4PWjMJjktixtrxF6BY405qyA50Sv967kEP2x-oil6qk,1120
|
|
2
|
-
iatoolkit/base_company.py,sha256=
|
|
2
|
+
iatoolkit/base_company.py,sha256=vU4ki-wB3PWIn3_Bvehfh0TfBH_XNC614tRBKNmEd84,4718
|
|
3
3
|
iatoolkit/cli_commands.py,sha256=G5L9xQXZ0lVFXQWBaE_KEZHyfuiT6PL1nTQRoSdnBzc,2302
|
|
4
4
|
iatoolkit/company_registry.py,sha256=tduqt3oV8iDX_IB1eA7KIgvIxE4edTcy-3qZIXh3Lzw,2549
|
|
5
|
-
iatoolkit/iatoolkit.py,sha256=
|
|
5
|
+
iatoolkit/iatoolkit.py,sha256=N922fz-tHZYZSpu5_PupW8p4x1yi66wnRq7UUgpPCfs,17583
|
|
6
6
|
iatoolkit/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
iatoolkit/common/exceptions.py,sha256=EXx40n5htp7UiOM6P1xfJ9U6NMcADqm62dlFaKz7ICU,1154
|
|
8
8
|
iatoolkit/common/routes.py,sha256=en9LNxQ3oj7wPUA19okmauGVqdA1yIB_YjPo_-CV-UQ,6195
|
|
@@ -29,7 +29,7 @@ iatoolkit/repositories/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCL
|
|
|
29
29
|
iatoolkit/repositories/database_manager.py,sha256=QgV8hNnVv9RmeOvUdomdj_mfk0bf3Rl8Ti41a-5zIAY,3700
|
|
30
30
|
iatoolkit/repositories/document_repo.py,sha256=Y7bF1kZB1HWJsAGjWdF7P2aVYeTYNufq9ngQXp7mDkY,1124
|
|
31
31
|
iatoolkit/repositories/llm_query_repo.py,sha256=YT_t7cYGQk8rwzH_17-28aTzO-e2jUfa2rvXy8tugvA,3612
|
|
32
|
-
iatoolkit/repositories/models.py,sha256=
|
|
32
|
+
iatoolkit/repositories/models.py,sha256=6KQpyCtp2l-ExfbeoPmoqc2V5qlTmSmEbzHYISZtu6g,14288
|
|
33
33
|
iatoolkit/repositories/profile_repo.py,sha256=21am3GP7XCG0nq6i3pArQ7mfGsrRn8rdcWT98fsdwlU,4397
|
|
34
34
|
iatoolkit/repositories/tasks_repo.py,sha256=icVO_r2oPagGnnBhwVFzznnvEEU2EAx-2dlWuWvoDC4,1745
|
|
35
35
|
iatoolkit/repositories/vs_repo.py,sha256=UkpmQQiocgM5IwRBmmWhw3HHzHP6zK1nN3J3TcQgjhc,5300
|
|
@@ -52,11 +52,11 @@ iatoolkit/services/query_service.py,sha256=gtMEAQ7IRVrFAMq4h_Pc_lHlMlXFI6heLSuBY
|
|
|
52
52
|
iatoolkit/services/search_service.py,sha256=i1xGWu7ORKIIDH0aAQBkF86dVVbLQ0Yrooz5TiZ6aGo,1823
|
|
53
53
|
iatoolkit/services/sql_service.py,sha256=MIslAtpJWnTMgSD74nnqTvQj27p-lHiyRXc6OiA2C_c,2172
|
|
54
54
|
iatoolkit/services/tasks_service.py,sha256=itREO5rDnUIgsqtyCOBKDtH30QL5v1egs4qPTiBK8xU,6865
|
|
55
|
-
iatoolkit/services/user_feedback_service.py,sha256=
|
|
55
|
+
iatoolkit/services/user_feedback_service.py,sha256=Bb6PVWcxzoQ3awev_k4MI0BQhkMh6iLPGC8_CK02t5g,4986
|
|
56
56
|
iatoolkit/services/user_session_context_service.py,sha256=vYF_vWM37tPB_ZyPBJ6f6WTJVjT2j-4L8JfZbqbI93k,6775
|
|
57
57
|
iatoolkit/static/images/fernando.jpeg,sha256=W68TYMuo5hZVpbP-evwH6Nu4xWFv2bc8pJzSKDoLTeQ,100612
|
|
58
58
|
iatoolkit/static/js/chat_context_reload.js,sha256=DCOGEf7-t_YLw9wuqkP-kFpiFHt3UyaesFfePp9Cs_k,2512
|
|
59
|
-
iatoolkit/static/js/chat_feedback.js,sha256=
|
|
59
|
+
iatoolkit/static/js/chat_feedback.js,sha256=j2LieutME4RrtMmHbyi3ptfRLefcxechule2NLxzCm8,4284
|
|
60
60
|
iatoolkit/static/js/chat_filepond.js,sha256=mzXafm7a506EpM37KATTK3zvAswO1E0KSUY1vKbwuRc,3163
|
|
61
61
|
iatoolkit/static/js/chat_history.js,sha256=4h6ldU7cDvgkW84fMKB8JReoxCX0NKSQAir_4CzAF9I,4382
|
|
62
62
|
iatoolkit/static/js/chat_main.js,sha256=o1ZNkeaBgGG9d07e5BxTL9OI0aJ26z1bvca1lGoQ-Uo,18535
|
|
@@ -103,9 +103,9 @@ iatoolkit/views/prompt_api_view.py,sha256=MP0r-MiswwKcbNc_5KY7aVbHkrR218I8XCiCX1
|
|
|
103
103
|
iatoolkit/views/signup_view.py,sha256=BCjhM2lMiDPwYrlW_eEwPl-ZLupblbFfsonWtq0E4vU,3922
|
|
104
104
|
iatoolkit/views/tasks_review_view.py,sha256=keLsLCyOTTlcoIapnB_lbuSvLwrPVZVpBiFC_7ChbLg,3388
|
|
105
105
|
iatoolkit/views/tasks_view.py,sha256=a3anTXrJTTvbQuc6PSpOzidLKQFL4hWa7PI2Cppcz8w,4110
|
|
106
|
-
iatoolkit/views/user_feedback_api_view.py,sha256=
|
|
106
|
+
iatoolkit/views/user_feedback_api_view.py,sha256=PNtXs3G26COw3QeZ9WlX14lYizualGMZ4wVfv77IUoU,2075
|
|
107
107
|
iatoolkit/views/verify_user_view.py,sha256=7XLSaxvs8LjBr3cYOUDa9B8DqW_50IGlq0IvmOQcD0Y,2340
|
|
108
|
-
iatoolkit-0.59.
|
|
109
|
-
iatoolkit-0.59.
|
|
110
|
-
iatoolkit-0.59.
|
|
111
|
-
iatoolkit-0.59.
|
|
108
|
+
iatoolkit-0.59.2.dist-info/METADATA,sha256=XUACxsD5jRzps23Y-avo13tfLAXlF23w7v2jrq-Pr4Q,9301
|
|
109
|
+
iatoolkit-0.59.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
110
|
+
iatoolkit-0.59.2.dist-info/top_level.txt,sha256=V_w4QvDx0b1RXiy8zTCrD1Bp7AZkFe3_O0-9fMiwogg,10
|
|
111
|
+
iatoolkit-0.59.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|