iatoolkit 0.11.0__py3-none-any.whl → 0.71.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.
Files changed (122) hide show
  1. iatoolkit/__init__.py +2 -6
  2. iatoolkit/base_company.py +9 -29
  3. iatoolkit/cli_commands.py +1 -1
  4. iatoolkit/common/routes.py +96 -52
  5. iatoolkit/common/session_manager.py +2 -1
  6. iatoolkit/common/util.py +17 -27
  7. iatoolkit/company_registry.py +1 -2
  8. iatoolkit/iatoolkit.py +97 -53
  9. iatoolkit/infra/llm_client.py +15 -20
  10. iatoolkit/infra/llm_proxy.py +38 -10
  11. iatoolkit/infra/openai_adapter.py +1 -1
  12. iatoolkit/infra/redis_session_manager.py +48 -2
  13. iatoolkit/locales/en.yaml +167 -0
  14. iatoolkit/locales/es.yaml +163 -0
  15. iatoolkit/repositories/database_manager.py +23 -3
  16. iatoolkit/repositories/document_repo.py +1 -1
  17. iatoolkit/repositories/models.py +35 -10
  18. iatoolkit/repositories/profile_repo.py +3 -2
  19. iatoolkit/repositories/vs_repo.py +26 -20
  20. iatoolkit/services/auth_service.py +193 -0
  21. iatoolkit/services/branding_service.py +70 -25
  22. iatoolkit/services/company_context_service.py +155 -0
  23. iatoolkit/services/configuration_service.py +133 -0
  24. iatoolkit/services/dispatcher_service.py +80 -105
  25. iatoolkit/services/document_service.py +5 -2
  26. iatoolkit/services/embedding_service.py +146 -0
  27. iatoolkit/services/excel_service.py +30 -26
  28. iatoolkit/services/file_processor_service.py +4 -12
  29. iatoolkit/services/history_service.py +7 -16
  30. iatoolkit/services/i18n_service.py +104 -0
  31. iatoolkit/services/jwt_service.py +18 -29
  32. iatoolkit/services/language_service.py +83 -0
  33. iatoolkit/services/load_documents_service.py +100 -113
  34. iatoolkit/services/mail_service.py +9 -4
  35. iatoolkit/services/profile_service.py +152 -76
  36. iatoolkit/services/prompt_manager_service.py +20 -16
  37. iatoolkit/services/query_service.py +208 -96
  38. iatoolkit/services/search_service.py +11 -4
  39. iatoolkit/services/sql_service.py +57 -25
  40. iatoolkit/services/tasks_service.py +1 -1
  41. iatoolkit/services/user_feedback_service.py +72 -34
  42. iatoolkit/services/user_session_context_service.py +112 -54
  43. iatoolkit/static/images/fernando.jpeg +0 -0
  44. iatoolkit/static/js/chat_feedback_button.js +80 -0
  45. iatoolkit/static/js/chat_help_content.js +124 -0
  46. iatoolkit/static/js/chat_history_button.js +110 -0
  47. iatoolkit/static/js/chat_logout_button.js +36 -0
  48. iatoolkit/static/js/chat_main.js +135 -222
  49. iatoolkit/static/js/chat_onboarding_button.js +103 -0
  50. iatoolkit/static/js/chat_prompt_manager.js +94 -0
  51. iatoolkit/static/js/chat_reload_button.js +35 -0
  52. iatoolkit/static/styles/chat_iatoolkit.css +289 -210
  53. iatoolkit/static/styles/chat_modal.css +63 -77
  54. iatoolkit/static/styles/chat_public.css +107 -0
  55. iatoolkit/static/styles/landing_page.css +182 -0
  56. iatoolkit/static/styles/onboarding.css +176 -0
  57. iatoolkit/system_prompts/query_main.prompt +5 -22
  58. iatoolkit/templates/_company_header.html +20 -0
  59. iatoolkit/templates/_login_widget.html +42 -0
  60. iatoolkit/templates/base.html +40 -20
  61. iatoolkit/templates/change_password.html +57 -36
  62. iatoolkit/templates/chat.html +180 -86
  63. iatoolkit/templates/chat_modals.html +138 -68
  64. iatoolkit/templates/error.html +44 -8
  65. iatoolkit/templates/forgot_password.html +40 -23
  66. iatoolkit/templates/index.html +145 -0
  67. iatoolkit/templates/login_simulation.html +45 -0
  68. iatoolkit/templates/onboarding_shell.html +107 -0
  69. iatoolkit/templates/signup.html +63 -65
  70. iatoolkit/views/base_login_view.py +91 -0
  71. iatoolkit/views/change_password_view.py +56 -31
  72. iatoolkit/views/embedding_api_view.py +65 -0
  73. iatoolkit/views/external_login_view.py +61 -28
  74. iatoolkit/views/{file_store_view.py → file_store_api_view.py} +10 -3
  75. iatoolkit/views/forgot_password_view.py +27 -21
  76. iatoolkit/views/help_content_api_view.py +54 -0
  77. iatoolkit/views/history_api_view.py +56 -0
  78. iatoolkit/views/home_view.py +50 -23
  79. iatoolkit/views/index_view.py +14 -0
  80. iatoolkit/views/init_context_api_view.py +74 -0
  81. iatoolkit/views/llmquery_api_view.py +58 -0
  82. iatoolkit/views/login_simulation_view.py +93 -0
  83. iatoolkit/views/login_view.py +130 -37
  84. iatoolkit/views/logout_api_view.py +49 -0
  85. iatoolkit/views/profile_api_view.py +46 -0
  86. iatoolkit/views/{prompt_view.py → prompt_api_view.py} +10 -10
  87. iatoolkit/views/signup_view.py +41 -36
  88. iatoolkit/views/{tasks_view.py → tasks_api_view.py} +10 -36
  89. iatoolkit/views/tasks_review_api_view.py +55 -0
  90. iatoolkit/views/user_feedback_api_view.py +60 -0
  91. iatoolkit/views/verify_user_view.py +34 -29
  92. {iatoolkit-0.11.0.dist-info → iatoolkit-0.71.2.dist-info}/METADATA +41 -23
  93. iatoolkit-0.71.2.dist-info/RECORD +122 -0
  94. iatoolkit-0.71.2.dist-info/licenses/LICENSE +21 -0
  95. iatoolkit/common/auth.py +0 -200
  96. iatoolkit/static/images/arrow_up.png +0 -0
  97. iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
  98. iatoolkit/static/images/logo_clinica.png +0 -0
  99. iatoolkit/static/images/logo_iatoolkit.png +0 -0
  100. iatoolkit/static/images/logo_maxxa.png +0 -0
  101. iatoolkit/static/images/logo_notaria.png +0 -0
  102. iatoolkit/static/images/logo_tarjeta.png +0 -0
  103. iatoolkit/static/images/logo_umayor.png +0 -0
  104. iatoolkit/static/images/upload.png +0 -0
  105. iatoolkit/static/js/chat_feedback.js +0 -115
  106. iatoolkit/static/js/chat_history.js +0 -117
  107. iatoolkit/static/styles/chat_info.css +0 -53
  108. iatoolkit/templates/header.html +0 -31
  109. iatoolkit/templates/home.html +0 -199
  110. iatoolkit/templates/login.html +0 -43
  111. iatoolkit/templates/test.html +0 -9
  112. iatoolkit/views/chat_token_request_view.py +0 -98
  113. iatoolkit/views/chat_view.py +0 -58
  114. iatoolkit/views/download_file_view.py +0 -58
  115. iatoolkit/views/external_chat_login_view.py +0 -95
  116. iatoolkit/views/history_view.py +0 -57
  117. iatoolkit/views/llmquery_view.py +0 -65
  118. iatoolkit/views/tasks_review_view.py +0 -83
  119. iatoolkit/views/user_feedback_view.py +0 -74
  120. iatoolkit-0.11.0.dist-info/RECORD +0 -110
  121. {iatoolkit-0.11.0.dist-info → iatoolkit-0.71.2.dist-info}/WHEEL +0 -0
  122. {iatoolkit-0.11.0.dist-info → iatoolkit-0.71.2.dist-info}/top_level.txt +0 -0
@@ -1,58 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from flask import render_template, request, jsonify
7
- from iatoolkit.services.profile_service import ProfileService
8
- from flask.views import MethodView
9
- from injector import inject
10
- import os
11
- from iatoolkit.common.auth import IAuthentication
12
- from iatoolkit.services.prompt_manager_service import PromptService
13
- from iatoolkit.services.branding_service import BrandingService
14
-
15
-
16
- class ChatView(MethodView):
17
- @inject
18
- def __init__(self,
19
- iauthentication: IAuthentication,
20
- prompt_service: PromptService,
21
- profile_service: ProfileService,
22
- branding_service: BrandingService
23
- ):
24
- self.iauthentication = iauthentication
25
- self.profile_service = profile_service
26
- self.prompt_service = prompt_service
27
- self.branding_service = branding_service
28
-
29
- def get(self, company_short_name: str):
30
- # get access credentials
31
- iaut = self.iauthentication.verify(company_short_name)
32
- if not iaut.get("success"):
33
- return jsonify(iaut), 401
34
-
35
- user_agent = request.user_agent
36
- is_mobile = user_agent.platform in ["android", "iphone", "ipad"] or "mobile" in user_agent.string.lower()
37
- alert_message = request.args.get('alert_message', None)
38
-
39
- # 1. get company info
40
- company = self.profile_service.get_company_by_short_name(company_short_name)
41
- if not company:
42
- return render_template('error.html', message="Empresa no encontrada"), 404
43
-
44
- # 2. get the company prompts
45
- prompts = self.prompt_service.get_user_prompts(company_short_name)
46
-
47
- # 3. get the branding data
48
- branding_data = self.branding_service.get_company_branding(company)
49
-
50
- return render_template("chat.html",
51
- branding=branding_data,
52
- company_short_name=company_short_name,
53
- is_mobile=is_mobile,
54
- alert_message=alert_message,
55
- alert_icon='success' if alert_message else None,
56
- iatoolkit_base_url=os.getenv('IATOOLKIT_BASE_URL', 'http://localhost:5000'),
57
- prompts=prompts
58
- )
@@ -1,58 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- import logging
7
- import os
8
-
9
- from flask import current_app, jsonify, send_from_directory
10
- from flask.views import MethodView
11
- from injector import inject
12
-
13
- from iatoolkit.common.auth import IAuthentication
14
- from iatoolkit.services.excel_service import ExcelService
15
- from iatoolkit.services.profile_service import ProfileService
16
-
17
-
18
- class DownloadFileView(MethodView):
19
- @inject
20
- def __init__(self, iauthentication: IAuthentication, profile_service: ProfileService, excel_service: ExcelService):
21
- self.iauthentication = iauthentication
22
- self.profile_service = profile_service
23
- self.excel_service = excel_service
24
-
25
- def get(self, company_short_name: str, external_user_id: str, filename: str):
26
- if not external_user_id:
27
- return jsonify({"error": "Falta external_user_id"}), 400
28
-
29
- iauth = self.iauthentication.verify(
30
- company_short_name,
31
- body_external_user_id=external_user_id
32
- )
33
- if not iauth.get("success"):
34
- return jsonify(iauth), 401
35
-
36
- company = self.profile_service.get_company_by_short_name(company_short_name)
37
- if not company:
38
- return jsonify({"error": "Empresa no encontrada"}), 404
39
-
40
- file_validation = self.excel_service.validate_file_access(filename)
41
- if file_validation:
42
- return file_validation
43
-
44
- temp_dir = os.path.join(current_app.root_path, 'static', 'temp')
45
-
46
- try:
47
- response = send_from_directory(
48
- temp_dir,
49
- filename,
50
- as_attachment=True,
51
- mimetype='application/octet-stream'
52
- )
53
- logging.info(f"Archivo descargado via API: {filename}")
54
- return response
55
- except Exception as e:
56
- logging.error(f"Error descargando archivo {filename}: {str(e)}")
57
- return jsonify({"error": "Error descargando archivo"}), 500
58
-
@@ -1,95 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- import os
7
- import logging
8
- from flask import request, jsonify, render_template
9
- from flask.views import MethodView
10
- from injector import inject
11
- from iatoolkit.common.auth import IAuthentication
12
- from iatoolkit.services.profile_service import ProfileService
13
- from iatoolkit.services.query_service import QueryService
14
- from iatoolkit.services.prompt_manager_service import PromptService
15
- from iatoolkit.services.jwt_service import JWTService
16
- from iatoolkit.services.branding_service import BrandingService
17
-
18
- class ExternalChatLoginView(MethodView):
19
- @inject
20
- def __init__(self,
21
- profile_service: ProfileService,
22
- query_service: QueryService,
23
- prompt_service: PromptService,
24
- iauthentication: IAuthentication,
25
- jwt_service: JWTService,
26
- branding_service: BrandingService
27
- ):
28
- self.profile_service = profile_service
29
- self.query_service = query_service
30
- self.prompt_service = prompt_service
31
- self.iauthentication = iauthentication
32
- self.jwt_service = jwt_service
33
- self.branding_service = branding_service
34
-
35
- def post(self, company_short_name: str):
36
- data = request.get_json()
37
- if not data or 'external_user_id' not in data:
38
- return jsonify({"error": "Falta external_user_id"}), 400
39
-
40
- external_user_id = data['external_user_id']
41
-
42
- # 1. get access credentials
43
- iaut = self.iauthentication.verify(
44
- company_short_name,
45
- body_external_user_id=external_user_id
46
- )
47
- if not iaut.get("success"):
48
- return jsonify(iaut), 401
49
-
50
- company = self.profile_service.get_company_by_short_name(company_short_name)
51
- if not company:
52
- return jsonify({"error": "Empresa no encontrada"}), 404
53
-
54
- try:
55
- # 1. generate a new JWT, our secure access token.
56
- token = self.jwt_service.generate_chat_jwt(
57
- company_id=company.id,
58
- company_short_name=company.short_name,
59
- external_user_id=external_user_id,
60
- expires_delta_seconds=3600 * 8 # 8 horas
61
- )
62
- if not token:
63
- raise Exception("No se pudo generar el token de sesión (JWT).")
64
-
65
- # 2. init the company/user LLM context.
66
- self.query_service.llm_init_context(
67
- company_short_name=company_short_name,
68
- external_user_id=external_user_id
69
- )
70
-
71
- # 3. get the prompt list from backend
72
- prompts = self.prompt_service.get_user_prompts(company_short_name)
73
-
74
- # 4. get the branding data
75
- branding_data = self.branding_service.get_company_branding(company)
76
-
77
- # 5. render the chat page with the company/user information.
78
- user_agent = request.user_agent
79
- is_mobile = user_agent.platform in ["android", "iphone", "ipad"] or "mobile" in user_agent.string.lower()
80
-
81
- chat_html = render_template("chat.html",
82
- company_short_name=company_short_name,
83
- branding=branding_data,
84
- external_user_id=external_user_id,
85
- is_mobile=is_mobile,
86
- auth_method='jwt', # login method is JWT
87
- session_jwt=token, # pass the token to the front-end
88
- iatoolkit_base_url=os.getenv('IATOOLKIT_BASE_URL'),
89
- prompts=prompts,
90
- external_login=True)
91
- return chat_html, 200
92
-
93
- except Exception as e:
94
- logging.exception(f"Error al inicializar el chat para {company_short_name}/{external_user_id}: {e}")
95
- return jsonify({"error": "Error interno al iniciar el chat"}), 500
@@ -1,57 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from flask import request, jsonify, render_template
7
- from flask.views import MethodView
8
- from iatoolkit.services.history_service import HistoryService
9
- from iatoolkit.common.auth import IAuthentication
10
- from injector import inject
11
- import logging
12
-
13
-
14
- class HistoryView(MethodView):
15
- @inject
16
- def __init__(self,
17
- iauthentication: IAuthentication,
18
- history_service: HistoryService ):
19
- self.iauthentication = iauthentication
20
- self.history_service = history_service
21
-
22
- def post(self, company_short_name):
23
- try:
24
- data = request.get_json()
25
- except Exception:
26
- return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
27
-
28
- if not data:
29
- return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
30
-
31
- # get access credentials
32
- iaut = self.iauthentication.verify(company_short_name, data.get("external_user_id"))
33
- if not iaut.get("success"):
34
- return jsonify(iaut), 401
35
-
36
- external_user_id = data.get("external_user_id")
37
- local_user_id = data.get("local_user_id", 0)
38
-
39
- try:
40
- response = self.history_service.get_history(
41
- company_short_name=company_short_name,
42
- external_user_id=external_user_id,
43
- local_user_id=local_user_id
44
- )
45
-
46
- if "error" in response:
47
- return {'error_message': response["error"]}, 402
48
-
49
- return response, 200
50
- except Exception as e:
51
- logging.exception(
52
- f"Error inesperado al obtener el historial de consultas para company {company_short_name}: {e}")
53
- if local_user_id:
54
- return render_template("error.html",
55
- message="Ha ocurrido un error inesperado."), 500
56
- else:
57
- return jsonify({"error_message": str(e)}), 500
@@ -1,65 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from flask import request, jsonify, render_template
7
- from flask.views import MethodView
8
- from iatoolkit.services.query_service import QueryService
9
- from iatoolkit.common.auth import IAuthentication
10
- from injector import inject
11
- import logging
12
-
13
-
14
- class LLMQueryView(MethodView):
15
- @inject
16
- def __init__(self,
17
- iauthentication: IAuthentication,
18
- query_service: QueryService,
19
- ):
20
- self.iauthentication = iauthentication
21
- self.query_service = query_service
22
-
23
- def post(self, company_short_name):
24
- data = request.get_json()
25
- if not data:
26
- return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
27
-
28
- # get access credentials
29
- iaut = self.iauthentication.verify(company_short_name, data.get("external_user_id"))
30
- if not iaut.get("success"):
31
- return jsonify(iaut), 401
32
-
33
- company_id = iaut.get("company_id")
34
- external_user_id = iaut.get("external_user_id")
35
- local_user_id = iaut.get("local_user_id")
36
-
37
- # now check the form
38
- question = data.get("question")
39
- files = data.get("files", [])
40
- client_data = data.get("client_data", {})
41
- prompt_name = data.get("prompt_name")
42
- if not question and not prompt_name:
43
- return jsonify({"error_message": "Falta la consulta o el prompt_name"}), 400
44
-
45
- try:
46
- response = self.query_service.llm_query(
47
- company_short_name=company_short_name,
48
- external_user_id=external_user_id,
49
- local_user_id=local_user_id,
50
- question=question,
51
- prompt_name=prompt_name,
52
- client_data=client_data,
53
- files=files)
54
- if "error" in response:
55
- return {'error_message': response.get("error_message", '')}, 401
56
-
57
- return response, 200
58
- except Exception as e:
59
- logging.exception(
60
- f"Error inesperado al procesar llm_query para company {company_short_name}: {e}")
61
- if local_user_id:
62
- return render_template("error.html",
63
- message="Ha ocurrido un error inesperado."), 500
64
- else:
65
- return jsonify({"error_message": str(e)}), 500
@@ -1,83 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from flask.views import MethodView
7
- from flask import request, jsonify
8
- from iatoolkit.services.tasks_service import TaskService
9
- from iatoolkit.repositories.profile_repo import ProfileRepo
10
- from injector import inject
11
- import logging
12
- from typing import Optional
13
-
14
-
15
- class TaskReviewView(MethodView):
16
- @inject
17
- def __init__(self, task_service: TaskService, profile_repo: ProfileRepo):
18
- self.task_service = task_service
19
- self.profile_repo = profile_repo
20
-
21
-
22
- def _authenticate_requesting_company_via_api_key(self) -> tuple[
23
- Optional[int], Optional[str], Optional[tuple[dict, int]]]:
24
- """
25
- Autentica a la compañía usando su API Key.
26
- Retorna (company_id, company_short_name, None) en éxito.
27
- Retorna (None, None, (error_json, status_code)) en fallo.
28
- """
29
- api_key_header = request.headers.get('Authorization')
30
- if not api_key_header or not api_key_header.startswith('Bearer '):
31
- return None, None, ({"error": "API Key faltante o mal formada en el header Authorization"}, 401)
32
-
33
- api_key_value = api_key_header.split('Bearer ')[1]
34
- try:
35
- api_key_entry = self.profile_repo.get_active_api_key_entry(api_key_value)
36
- if not api_key_entry:
37
- return None, None, ({"error": "API Key inválida o inactiva"}, 401)
38
-
39
- # api_key_entry.company ya está cargado por joinedload en get_active_api_key_entry
40
- if not api_key_entry.company: # Sanity check
41
- logging.error(
42
- f"ChatTokenRequest: API Key {api_key_value[:5]}... no tiene compañía asociada a pesar de ser válida.")
43
- return None, None, ({"error": "Error interno del servidor al verificar API Key"}, 500)
44
-
45
- return api_key_entry.company_id, api_key_entry.company.short_name, None
46
-
47
- except Exception as e:
48
- logging.exception(f"ChatTokenRequest: Error interno durante validación de API Key: {e}")
49
- return None, None, ({"error": "Error interno del servidor al validar API Key"}, 500)
50
-
51
-
52
- def post(self, task_id: int):
53
- try:
54
- # only requests with valid api-key are allowed
55
- auth_company_id, auth_company_short_name, error = self._authenticate_requesting_company_via_api_key()
56
- if error:
57
- return jsonify(error[0]), error[1]
58
-
59
- req_data = request.get_json()
60
-
61
- required_fields = ['review_user', 'approved']
62
- for field in required_fields:
63
- if field not in req_data:
64
- return jsonify({"error": f"El campo {field} es requerido"}), 400
65
-
66
- review_user = req_data.get('review_user', '')
67
- approved = req_data.get('approved', False)
68
- comment = req_data.get('comment', '')
69
-
70
- new_task = self.task_service.review_task(
71
- task_id=task_id,
72
- review_user=review_user,
73
- approved=approved,
74
- comment=comment)
75
-
76
- return jsonify({
77
- "task_id": new_task.id,
78
- "status": new_task.status.name
79
- }), 200
80
-
81
- except Exception as e:
82
- logging.exception("Error al revisar la tarea: %s", str(e))
83
- return jsonify({"error": str(e)}), 500
@@ -1,74 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from flask import request, jsonify, render_template
7
- from flask.views import MethodView
8
- from iatoolkit.services.user_feedback_service import UserFeedbackService
9
- from iatoolkit.common.auth import IAuthentication
10
- from injector import inject
11
- import logging
12
-
13
-
14
- class UserFeedbackView(MethodView):
15
- @inject
16
- def __init__(self,
17
- iauthentication: IAuthentication,
18
- user_feedback_service: UserFeedbackService ):
19
- self.iauthentication = iauthentication
20
- self.user_feedback_service = user_feedback_service
21
-
22
- def post(self, company_short_name):
23
- data = request.get_json()
24
- if not data:
25
- return jsonify({"error_message": "Cuerpo de la solicitud JSON inválido o faltante"}), 400
26
-
27
- # get access credentials
28
- iaut = self.iauthentication.verify(company_short_name, data.get("external_user_id"))
29
- if not iaut.get("success"):
30
- return jsonify(iaut), 401
31
-
32
- message = data.get("message")
33
- if not message:
34
- return jsonify({"error_message": "Falta el mensaje de feedback"}), 400
35
-
36
- space = data.get("space")
37
- if not space:
38
- return jsonify({"error_message": "Falta el espacio de Google Chat"}), 400
39
-
40
- type = data.get("type")
41
- if not type:
42
- return jsonify({"error_message": "Falta el tipo de feedback"}), 400
43
-
44
- rating = data.get("rating")
45
- if not rating:
46
- return jsonify({"error_message": "Falta la calificación"}), 400
47
-
48
- external_user_id = data.get("external_user_id")
49
- local_user_id = data.get("local_user_id", 0)
50
-
51
- try:
52
- response = self.user_feedback_service.new_feedback(
53
- company_short_name=company_short_name,
54
- message=message,
55
- external_user_id=external_user_id,
56
- local_user_id=local_user_id,
57
- space=space,
58
- type=type,
59
- rating=rating
60
- )
61
-
62
- if "error" in response:
63
- return {'error_message': response["error"]}, 402
64
-
65
- return response, 200
66
- except Exception as e:
67
- logging.exception(
68
- f"Error inesperado al procesar feedback para company {company_short_name}: {e}")
69
- if local_user_id:
70
- return render_template("error.html",
71
- message="Ha ocurrido un error inesperado."), 500
72
- else:
73
- return jsonify({"error_message": str(e)}), 500
74
-
@@ -1,110 +0,0 @@
1
- iatoolkit/__init__.py,sha256=4PWjMJjktixtrxF6BY405qyA50Sv967kEP2x-oil6qk,1120
2
- iatoolkit/base_company.py,sha256=4usUdOC57Nk1XsawAEyC7mlzb0jROadu64YcYf6poiM,4371
3
- iatoolkit/cli_commands.py,sha256=G5L9xQXZ0lVFXQWBaE_KEZHyfuiT6PL1nTQRoSdnBzc,2302
4
- iatoolkit/company_registry.py,sha256=tduqt3oV8iDX_IB1eA7KIgvIxE4edTcy-3qZIXh3Lzw,2549
5
- iatoolkit/iatoolkit.py,sha256=EXmHQEgLCqbBP7Cwq6-O1NPj7O3M_2Cg9JLp5xa41ig,16960
6
- iatoolkit/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- iatoolkit/common/auth.py,sha256=8NH6MQXfddLQd1GxrO2op3IYrrP4SMQKoKzj1o1jZmc,8486
8
- iatoolkit/common/exceptions.py,sha256=EXx40n5htp7UiOM6P1xfJ9U6NMcADqm62dlFaKz7ICU,1154
9
- iatoolkit/common/routes.py,sha256=8_wvrFiB5w5Sq-5gZfIDz9JVPROd9JED5oxkX1N87gY,4923
10
- iatoolkit/common/session_manager.py,sha256=7D_RuJs60w-1zDr3fOGEz9JW7IZlSXuUHgUT87CzaUo,472
11
- iatoolkit/common/util.py,sha256=08js3KLJTXICOd5sgwDp2u_kDaZO_0xG4BIuzWZnLo8,15535
12
- iatoolkit/infra/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
13
- iatoolkit/infra/call_service.py,sha256=iRk9VxbXaAwlLIl8fUzGDWIAdzwfsbs1MtP84YeENxg,4929
14
- iatoolkit/infra/gemini_adapter.py,sha256=kXV-t5i9GmWBafUPX2kAyiqvcT7GPoxHylcCUWG_c_U,15051
15
- iatoolkit/infra/google_chat_app.py,sha256=_uKWxeacHH6C5a4FVx0YZjBn1tL-x_MIQV9gqgWGAjo,1937
16
- iatoolkit/infra/llm_client.py,sha256=3w2BUQmnyq9Tbc9_CI2JjxZQ7pGVlMF_GmUdqBa9O7Y,18618
17
- iatoolkit/infra/llm_proxy.py,sha256=cHyNxUpVE4UDoWUfvSGfGCrIUFPTrpWZOixELQTsGFY,5744
18
- iatoolkit/infra/llm_response.py,sha256=YUUQPBHzmP3Ce6-t0kKMRIpowvh7de1odSoefEByIvI,904
19
- iatoolkit/infra/mail_app.py,sha256=PLGZdEs7LQ_9bmMRRxz0iqQdNa4xToAFyf9tg75wK8U,6103
20
- iatoolkit/infra/openai_adapter.py,sha256=Z1JSi3Tw2mXQ7JAh6yR79Ri_9yZJcJpcZLOLL3Mfda8,3530
21
- iatoolkit/infra/redis_session_manager.py,sha256=Dkwii8fns0_Vd9hm9GmotmrKtSCxVps868U5sqj7FAE,2278
22
- iatoolkit/infra/connectors/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
23
- iatoolkit/infra/connectors/file_connector.py,sha256=HOjRTFd-WfDOcFyvHncAhnGNZuFgChIwC-P6osPo9ZM,352
24
- iatoolkit/infra/connectors/file_connector_factory.py,sha256=3qvyfH4ZHKuiMxJFkawOxhW2-TGKKtsBYHgoPpZMuKU,2118
25
- iatoolkit/infra/connectors/google_cloud_storage_connector.py,sha256=IXpL3HTo7Ft4EQsYiQq5wXRRQK854jzOEB7ZdWjLa4U,2050
26
- iatoolkit/infra/connectors/google_drive_connector.py,sha256=WR1AlO5-Bl3W89opdja0kKgHTJzVOjTsy3H4SlIvwVg,2537
27
- iatoolkit/infra/connectors/local_file_connector.py,sha256=hrzIgpMJOTuwTqzlQeTIU_50ZbZ6yl8lcWPv6hMnoqI,1739
28
- iatoolkit/infra/connectors/s3_connector.py,sha256=Nj4_YaLobjfcnbZewJf21_K2EXohgcc3mJll1Pzn4zg,1123
29
- iatoolkit/repositories/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
30
- iatoolkit/repositories/database_manager.py,sha256=UaU7k3s7IRuXhCHTy9GoCeP9K1ad0LBdj_n1a_QjGS0,3108
31
- iatoolkit/repositories/document_repo.py,sha256=Y7bF1kZB1HWJsAGjWdF7P2aVYeTYNufq9ngQXp7mDkY,1124
32
- iatoolkit/repositories/llm_query_repo.py,sha256=YT_t7cYGQk8rwzH_17-28aTzO-e2jUfa2rvXy8tugvA,3612
33
- iatoolkit/repositories/models.py,sha256=vlSC-Z1cbho5dLrvoMnEroafO7yC3JXsZKn7SqoIXKU,13158
34
- iatoolkit/repositories/profile_repo.py,sha256=X2tnqAdaae-SA9sQq-gBqopVdf77I_Q9J_Aa38P0tjY,4060
35
- iatoolkit/repositories/tasks_repo.py,sha256=icVO_r2oPagGnnBhwVFzznnvEEU2EAx-2dlWuWvoDC4,1745
36
- iatoolkit/repositories/vs_repo.py,sha256=UkpmQQiocgM5IwRBmmWhw3HHzHP6zK1nN3J3TcQgjhc,5300
37
- iatoolkit/services/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
38
- iatoolkit/services/benchmark_service.py,sha256=CdbFYyS3FHFhNzWQEa9ZNjUlmON10DT1nKNbZQ1EUi8,5880
39
- iatoolkit/services/branding_service.py,sha256=OiyH8aRyy3Q3EWZDINXS-y9TkrIt-GcA7cK2esw_7Ws,4899
40
- iatoolkit/services/dispatcher_service.py,sha256=ykR1ye6McyCCuaBgwH6r3-PqcLAr4v4ApkPazMSBzbs,14040
41
- iatoolkit/services/document_service.py,sha256=nMXrNtbHQuc9pSaten0LvKY0kT8_WngBDmZJUP3jNPw,5936
42
- iatoolkit/services/excel_service.py,sha256=CJGhu7cQl9J6y_ZWSJ-M63Xm-RXR9Zs66oOR2NJErZQ,3868
43
- iatoolkit/services/file_processor_service.py,sha256=B1sUUhZNFf-rT4_1wrD38GKNoBFMp2g0dYrXYMCWe2E,4122
44
- iatoolkit/services/history_service.py,sha256=ZlYfaSHOcCxxc6ICTnqflaGBlzctpJdNUwXpUPG5xWI,1630
45
- iatoolkit/services/jwt_service.py,sha256=YoZ9h7_o9xBko-arNQv4MbcwnxoSWVNj4VbZmMo_QGY,3908
46
- iatoolkit/services/load_documents_service.py,sha256=ZpB0BZ3qX1fGJGBtZtMLbFdWWx0hkPoeCS3OqJKwCTs,7291
47
- iatoolkit/services/mail_service.py,sha256=2h-fcF3swZDya_o7IpgXkmuj3iEVHVCiHi7oVxU99sQ,2182
48
- iatoolkit/services/profile_service.py,sha256=azaCQtRJwQayg-3NV6k0lX97SFiF12emhz60S4CWv-M,17621
49
- iatoolkit/services/prompt_manager_service.py,sha256=U-XmSpkeXvv1KRN4dytdMxSYBMRSB7y-UHcb18mk0nA,8342
50
- iatoolkit/services/query_service.py,sha256=CI_LUBdqolvsuh7TjY23oaQcc8s6rmmr4LqnjE81ZJc,15394
51
- iatoolkit/services/search_service.py,sha256=i1xGWu7ORKIIDH0aAQBkF86dVVbLQ0Yrooz5TiZ6aGo,1823
52
- iatoolkit/services/sql_service.py,sha256=MIslAtpJWnTMgSD74nnqTvQj27p-lHiyRXc6OiA2C_c,2172
53
- iatoolkit/services/tasks_service.py,sha256=g0rBku8JSRuludFKJFNfKARJoKdX9JXISKNVe7wtH5A,6850
54
- iatoolkit/services/user_feedback_service.py,sha256=KW3VMgsH_ZNlBZIHr8eF49oO7jr75lPpr_1wWTEQYsc,2472
55
- iatoolkit/services/user_session_context_service.py,sha256=j8mKgmSyma6k_1FyXOXwpnYi9CrdEBCpPJA1eLHYZsg,3807
56
- iatoolkit/static/images/arrow_up.png,sha256=vPcWMebWVOOt13x5U7pzsyukysoiXO0siSyErUMleHw,2781
57
- iatoolkit/static/images/diagrama_iatoolkit.jpg,sha256=GhauwUVqWjt9dWtsW53Uon_mo61j73brmC4ogQc6tkY,93527
58
- iatoolkit/static/images/logo_clinica.png,sha256=vLX6X7O9RPUHYTQHvO_Fx28sI4JulpRZsRpkuJ9XIu0,56806
59
- iatoolkit/static/images/logo_iatoolkit.png,sha256=7XSxLy8v_mGxQMM8EA0gund-MmnQoIy1RV6DkJ-eukI,185089
60
- iatoolkit/static/images/logo_maxxa.png,sha256=X4JtTu6ooe2RUHRo1stxGGquXlkiEWcTUxH5vbFdMv0,10592
61
- iatoolkit/static/images/logo_notaria.png,sha256=FLDK1mHydFpzudKLKQSqHdSqq6vbqs77a_bO0PI_yHE,105105
62
- iatoolkit/static/images/logo_tarjeta.png,sha256=HQe2lp_jHFWq5hnx3SCBEcqW5IFfvSCktv9oyN--5cQ,1700
63
- iatoolkit/static/images/logo_umayor.png,sha256=FHr1wvI8uDn1YRbRcLSRLBOc0mYusHx9Um6ZzVZUbOQ,19199
64
- iatoolkit/static/images/upload.png,sha256=zh5FiINURpaWZQF86bF_gALBX4W1c4aLp5wPQO9xGXI,296
65
- iatoolkit/static/js/chat_feedback.js,sha256=_izl49hFEUZYREcJoaPukpTs0YjDgJYUu-QfPt5Ll2s,4398
66
- iatoolkit/static/js/chat_filepond.js,sha256=mzXafm7a506EpM37KATTK3zvAswO1E0KSUY1vKbwuRc,3163
67
- iatoolkit/static/js/chat_history.js,sha256=4eRLLjP5cn2F0FOWxqT4qMh49R2PDoGu1S3VyevIndw,3909
68
- iatoolkit/static/js/chat_main.js,sha256=yPBoWuTt2EpukiYJq-FRLmIQ6wC8Gc_kv1qE454W33c,15153
69
- iatoolkit/static/styles/chat_iatoolkit.css,sha256=R70M2BOhj0lo9gT0pBcjDwAaZwo-lG7agmmgIjwJfi0,9726
70
- iatoolkit/static/styles/chat_info.css,sha256=17DbgoNYE21VYWfb5L9-QLCpD2R1idK4imKRLwXtJLY,1058
71
- iatoolkit/static/styles/chat_modal.css,sha256=pE7JY5D63Ds_d2FKdmxym4sevvg-2Mf7yo-gB7KA9vE,3730
72
- iatoolkit/static/styles/llm_output.css,sha256=AlxgRSOleeCk2dLAqFWVaQ-jwZiJjcpC5rHuUv3T6VU,2312
73
- iatoolkit/system_prompts/format_styles.prompt,sha256=MSMe1qvR3cF_0IbFshn8R0z6Wx6VCHQq1p37rpu5wwk,3576
74
- iatoolkit/system_prompts/query_main.prompt,sha256=w_9ybgWgiQH4V_RbAXqsvz0M7oOuiyhxcwf-D0CgfA4,3017
75
- iatoolkit/system_prompts/sql_rules.prompt,sha256=y4nURVnb9AyFwt-lrbMNBHHtZlhk6kC9grYoOhRnrJo,59174
76
- iatoolkit/templates/about.html,sha256=ciC08grUVz5qLzdzDDqDX31xirg5PrJIRYabWpV9oA8,294
77
- iatoolkit/templates/base.html,sha256=LXXB8oPrcBFkf2pLfOSyAaSh66kHbs4SEujpFL3h9Nw,2163
78
- iatoolkit/templates/change_password.html,sha256=DFfQSFcZ2YJZNFis2IXfzEKStxTf4i9f4eQ_6GiyNs8,2342
79
- iatoolkit/templates/chat.html,sha256=IwUbjF5FpRxZEZ8Dz_qe_KTdAgfWatrKTuPhOsXqUlM,9306
80
- iatoolkit/templates/chat_modals.html,sha256=3CQ430bwhebq6rAJ6Bk12PQDjt9YenqNXm5thC5WP2Y,5771
81
- iatoolkit/templates/error.html,sha256=BNF-7z8AYL5vF4ZMUFMrOBt8c85kCFrm9qSHn9EiHWg,540
82
- iatoolkit/templates/forgot_password.html,sha256=1lUbKg9CKnQdnySplceY_pibwYne1-mOlM38fqI1kW8,1563
83
- iatoolkit/templates/header.html,sha256=179agI7rnYwP_rvJNXIiVde5E8Ec5649_XKq6eew2Hk,1263
84
- iatoolkit/templates/home.html,sha256=HpJmz0rCMBt3XYd83hecBCESvMg85n56PV5XvE_8Q_g,8201
85
- iatoolkit/templates/login.html,sha256=r4hy7MsQkfDqi6pBRNkkRiFr3GPSoHCT89R5lQLUWZc,1991
86
- iatoolkit/templates/signup.html,sha256=J8wOjUhUe_KozyThDTWHjXpSJ1ubR2IDVobThtkSRuo,3819
87
- iatoolkit/templates/test.html,sha256=rwNtxC83tbCl5COZFXYvmRBxxmgFJtPNuVBd_nq9KWY,133
88
- iatoolkit/views/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
89
- iatoolkit/views/change_password_view.py,sha256=rSebwecI1zwBgR2yvAhcfMwWpGDa4QbVAIllgtSOo9k,3940
90
- iatoolkit/views/chat_token_request_view.py,sha256=wf32_A2Sq8NHYWshCwL10Tovd1znLoD0jQjzutR3sVE,4408
91
- iatoolkit/views/chat_view.py,sha256=BD1N-Jo9IOoS6baX1bzdM7DKa2zepVHZnJIxiF0vNc8,2381
92
- iatoolkit/views/download_file_view.py,sha256=1gZ0ipqeCn39sTrJFo1-tlewlcSF7s_YNTvE4qd0HOw,2010
93
- iatoolkit/views/external_chat_login_view.py,sha256=h-Xr7UkQM7QxLZIDQ0fXb-BUfPbABQ1gjiP--FrXnpc,4075
94
- iatoolkit/views/external_login_view.py,sha256=EHxN2omqTDkWyMp0FVCNDFt-JJ2hpg8LvprKanGR1gY,1355
95
- iatoolkit/views/file_store_view.py,sha256=hUm5wX4E5oqJJEPEAObEj-nPiRp5EJIICULSfAWmHCs,1933
96
- iatoolkit/views/forgot_password_view.py,sha256=Rk8Qbe9Fz7Wlgje1rt29I15gFM-a089EBi2at4FT7kA,2715
97
- iatoolkit/views/history_view.py,sha256=8sqc9i8hN5bbRs3mSjurqKEZaXKANTQqATfwVAS4qSM,2064
98
- iatoolkit/views/home_view.py,sha256=TihO2flkelJa9j6a0FKCMVhD-2X7BhemonB7LTne4x8,1248
99
- iatoolkit/views/llmquery_view.py,sha256=rv2i3oeXlNc3Sv7Qu3DZGf37r-bMSa4N25FzG7_kPAI,2432
100
- iatoolkit/views/login_view.py,sha256=MI87rGB1QpxEVxWy-tR2q7s9ms9pcFLIW8ZmNQh1EFE,2332
101
- iatoolkit/views/prompt_view.py,sha256=l8KHlLmkSgSLK43VbhwKED7mCN9YyfeHHh4zvx0pT0E,1257
102
- iatoolkit/views/signup_view.py,sha256=NTx_2w8F6Np88FKEpDvBvJXU-bISKpDMdhhT4XFAVfk,3805
103
- iatoolkit/views/tasks_review_view.py,sha256=keLsLCyOTTlcoIapnB_lbuSvLwrPVZVpBiFC_7ChbLg,3388
104
- iatoolkit/views/tasks_view.py,sha256=a3anTXrJTTvbQuc6PSpOzidLKQFL4hWa7PI2Cppcz8w,4110
105
- iatoolkit/views/user_feedback_view.py,sha256=G37zmP8P4LvZrSymNJ5iFXhLZg1A3BEwRfTpH1Iam5w,2652
106
- iatoolkit/views/verify_user_view.py,sha256=a3q4wHJ8mKAEmgbNTOcnX4rMikROjOR3mHvCr30qGGA,2351
107
- iatoolkit-0.11.0.dist-info/METADATA,sha256=RT3k8OHHUmr7MPpEeS2pTCfQROC2lgQ1nFjGLA2nLCU,9301
108
- iatoolkit-0.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
- iatoolkit-0.11.0.dist-info/top_level.txt,sha256=V_w4QvDx0b1RXiy8zTCrD1Bp7AZkFe3_O0-9fMiwogg,10
110
- iatoolkit-0.11.0.dist-info/RECORD,,