iatoolkit 0.11.0__tar.gz → 0.12.0__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.
Potentially problematic release.
This version of iatoolkit might be problematic. Click here for more details.
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/PKG-INFO +1 -1
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/pyproject.toml +1 -1
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/common/routes.py +9 -7
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/iatoolkit.py +0 -4
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/branding_service.py +2 -1
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/profile_service.py +12 -20
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/js/chat_history.js +1 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/js/chat_main.js +76 -51
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +17 -1
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/chat.html +3 -2
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/home.html +3 -3
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/external_chat_login_view.py +34 -17
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/history_view.py +1 -1
- iatoolkit-0.12.0/src/iatoolkit/views/login_view.py +124 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit.egg-info/PKG-INFO +1 -1
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit.egg-info/SOURCES.txt +0 -1
- iatoolkit-0.11.0/src/iatoolkit/views/chat_view.py +0 -58
- iatoolkit-0.11.0/src/iatoolkit/views/login_view.py +0 -60
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/readme.md +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/requirements.txt +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/setup.cfg +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/base_company.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/cli_commands.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/common/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/common/auth.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/common/exceptions.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/common/session_manager.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/common/util.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/company_registry.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/call_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/gemini_adapter.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/llm_client.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/llm_response.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/mail_app.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/openai_adapter.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/database_manager.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/document_repo.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/models.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/profile_repo.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/tasks_repo.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/benchmark_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/document_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/excel_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/file_processor_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/history_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/jwt_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/load_documents_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/mail_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/prompt_manager_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/query_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/search_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/sql_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/tasks_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/arrow_up.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/logo_clinica.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/logo_iatoolkit.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/logo_maxxa.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/logo_notaria.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/logo_tarjeta.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/logo_umayor.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/images/upload.png +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/js/chat_feedback.js +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/styles/chat_info.css +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/about.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/base.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/change_password.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/chat_modals.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/error.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/forgot_password.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/header.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/login.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/signup.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/templates/test.html +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/__init__.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/change_password_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/chat_token_request_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/download_file_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/external_login_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/file_store_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/home_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/llmquery_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/prompt_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/signup_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/tasks_review_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/tasks_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/user_feedback_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/views/verify_user_view.py +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit.egg-info/top_level.txt +0 -0
|
@@ -26,9 +26,8 @@ def register_views(injector, app):
|
|
|
26
26
|
from iatoolkit.views.tasks_view import TaskView
|
|
27
27
|
from iatoolkit.views.tasks_review_view import TaskReviewView
|
|
28
28
|
from iatoolkit.views.home_view import HomeView
|
|
29
|
-
from iatoolkit.views.
|
|
30
|
-
from iatoolkit.views.
|
|
31
|
-
from iatoolkit.views.external_chat_login_view import ExternalChatLoginView
|
|
29
|
+
from iatoolkit.views.login_view import LoginView, InitiateLoginView
|
|
30
|
+
from iatoolkit.views.external_chat_login_view import InitiateExternalChatView, ExternalChatLoginView
|
|
32
31
|
from iatoolkit.views.signup_view import SignupView
|
|
33
32
|
from iatoolkit.views.verify_user_view import VerifyAccountView
|
|
34
33
|
from iatoolkit.views.forgot_password_view import ForgotPasswordView
|
|
@@ -42,16 +41,19 @@ def register_views(injector, app):
|
|
|
42
41
|
|
|
43
42
|
app.add_url_rule('/', view_func=HomeView.as_view('home'))
|
|
44
43
|
|
|
45
|
-
# main chat for iatoolkit front
|
|
46
|
-
app.add_url_rule('/<company_short_name>/chat', view_func=ChatView.as_view('chat'))
|
|
47
|
-
|
|
48
44
|
# front if the company internal portal
|
|
49
45
|
app.add_url_rule('/<company_short_name>/chat_login', view_func=ExternalChatLoginView.as_view('external_chat_login'))
|
|
50
|
-
app.add_url_rule('/<company_short_name>/external_login/<external_user_id>',
|
|
46
|
+
app.add_url_rule('/<company_short_name>/external_login/<external_user_id>',
|
|
47
|
+
view_func=ExternalLoginView.as_view('external_login'))
|
|
48
|
+
app.add_url_rule('/<company_short_name>/initiate_external_chat',
|
|
49
|
+
view_func=InitiateExternalChatView.as_view('initiate_chat_login'))
|
|
50
|
+
|
|
51
51
|
app.add_url_rule('/auth/chat_token', view_func=ChatTokenRequestView.as_view('chat-token'))
|
|
52
52
|
|
|
53
53
|
# main pages for the iatoolkit frontend
|
|
54
54
|
app.add_url_rule('/<company_short_name>/login', view_func=LoginView.as_view('login'))
|
|
55
|
+
app.add_url_rule('/<company_short_name>/initiate_login', view_func=InitiateLoginView.as_view('initiate_login'))
|
|
56
|
+
|
|
55
57
|
app.add_url_rule('/<company_short_name>/signup',view_func=SignupView.as_view('signup'))
|
|
56
58
|
app.add_url_rule('/<company_short_name>/logout', 'logout', logout)
|
|
57
59
|
app.add_url_rule('/logout', 'logout', logout)
|
|
@@ -315,12 +315,8 @@ class IAToolkit:
|
|
|
315
315
|
"""Vincula las vistas después de que el injector ha sido creado"""
|
|
316
316
|
from iatoolkit.views.llmquery_view import LLMQueryView
|
|
317
317
|
from iatoolkit.views.home_view import HomeView
|
|
318
|
-
from iatoolkit.views.chat_view import ChatView
|
|
319
|
-
from iatoolkit.views.change_password_view import ChangePasswordView
|
|
320
318
|
|
|
321
319
|
binder.bind(HomeView, to=HomeView)
|
|
322
|
-
binder.bind(ChatView, to=ChatView)
|
|
323
|
-
binder.bind(ChangePasswordView, to=ChangePasswordView)
|
|
324
320
|
binder.bind(LLMQueryView, to=LLMQueryView)
|
|
325
321
|
|
|
326
322
|
logging.info("✅ Views configuradas correctamente")
|
|
@@ -104,5 +104,6 @@ class BrandingService:
|
|
|
104
104
|
"secondary_text_style": secondary_text_style,
|
|
105
105
|
"tertiary_text_style": tertiary_text_style,
|
|
106
106
|
"header_text_color": final_branding_values['header_text_color'],
|
|
107
|
-
"css_variables": css_variables
|
|
107
|
+
"css_variables": css_variables,
|
|
108
|
+
"send_button_color": final_branding_values['send_button_color']
|
|
108
109
|
}
|
|
@@ -17,7 +17,6 @@ import secrets
|
|
|
17
17
|
import string
|
|
18
18
|
from datetime import datetime, timezone
|
|
19
19
|
from iatoolkit.services.user_session_context_service import UserSessionContextService
|
|
20
|
-
from iatoolkit.services.query_service import QueryService
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
class ProfileService:
|
|
@@ -25,50 +24,43 @@ class ProfileService:
|
|
|
25
24
|
def __init__(self,
|
|
26
25
|
profile_repo: ProfileRepo,
|
|
27
26
|
session_context_service: UserSessionContextService,
|
|
28
|
-
query_service: QueryService,
|
|
29
27
|
mail_app: MailApp):
|
|
30
28
|
self.profile_repo = profile_repo
|
|
31
29
|
self.session_context = session_context_service
|
|
32
|
-
self.query_service = query_service
|
|
33
30
|
self.mail_app = mail_app
|
|
34
31
|
self.bcrypt = Bcrypt()
|
|
35
32
|
|
|
36
33
|
|
|
37
34
|
def login(self, company_short_name: str, email: str, password: str) -> dict:
|
|
38
35
|
try:
|
|
39
|
-
# check if
|
|
36
|
+
# check if user exists
|
|
40
37
|
user = self.profile_repo.get_user_by_email(email)
|
|
41
38
|
if not user:
|
|
42
|
-
return {"
|
|
39
|
+
return {'success': False, "message": "Usuario no encontrado"}
|
|
43
40
|
|
|
44
41
|
# check the encrypted password
|
|
45
42
|
if not check_password_hash(user.password, password):
|
|
46
|
-
return {"
|
|
43
|
+
return {'success': False, "message": "Contraseña inválida"}
|
|
47
44
|
|
|
48
45
|
company = self.get_company_by_short_name(company_short_name)
|
|
49
46
|
if not company:
|
|
50
|
-
return {"
|
|
47
|
+
return {'success': False, "message": "Empresa no encontrada"}
|
|
51
48
|
|
|
52
|
-
# check that user belongs to
|
|
49
|
+
# check that user belongs to company
|
|
53
50
|
if company not in user.companies:
|
|
54
|
-
return {"
|
|
51
|
+
return {'success': False, "message": "Usuario no esta autorizado para esta empresa"}
|
|
55
52
|
|
|
56
53
|
if not user.verified:
|
|
57
|
-
return {
|
|
54
|
+
return {'success': False,
|
|
55
|
+
"message": "Tu cuenta no ha sido verificada. Por favor, revisa tu correo."}
|
|
58
56
|
|
|
59
|
-
#
|
|
57
|
+
# save user data into session manager
|
|
60
58
|
self.set_user_session(user=user, company=company)
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
self.query_service.llm_init_context(
|
|
64
|
-
company_short_name=company_short_name,
|
|
65
|
-
local_user_id=user.id
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
return {"message": "Login exitoso"}
|
|
60
|
+
return {'success': True, "user": user, "message": "Login exitoso"}
|
|
69
61
|
except Exception as e:
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
return {'success': False, "message": str(e)}
|
|
63
|
+
|
|
72
64
|
|
|
73
65
|
def set_user_session(self, user: User, company: Company):
|
|
74
66
|
SessionManager.set('user_id', user.id)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Global variables for request management
|
|
2
|
-
let currentAbortController = null;
|
|
3
2
|
let isRequestInProgress = false;
|
|
3
|
+
let abortController = null;
|
|
4
4
|
|
|
5
5
|
let selectedPrompt = null; // Will hold a lightweight prompt object
|
|
6
6
|
|
|
@@ -8,6 +8,8 @@ $(document).ready(function () {
|
|
|
8
8
|
// --- MAIN EVENT HANDLERS ---
|
|
9
9
|
$('#send-button').on('click', handleChatMessage);
|
|
10
10
|
$('#stop-button').on('click', abortCurrentRequest);
|
|
11
|
+
if (window.sendButtonColor)
|
|
12
|
+
$('#send-button i').css('color', window.sendButtonColor);
|
|
11
13
|
|
|
12
14
|
// --- PROMPT ASSISTANT FUNCTIONALITY ---
|
|
13
15
|
$('.input-area').on('click', '.dropdown-menu a.dropdown-item', function (event) {
|
|
@@ -118,75 +120,99 @@ function renderDynamicInputs(fields) {
|
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
|
|
123
|
+
|
|
121
124
|
/**
|
|
122
125
|
* Main function to handle sending a chat message.
|
|
123
126
|
*/
|
|
124
127
|
const handleChatMessage = async function () {
|
|
125
|
-
if (isRequestInProgress || $('#send-button').hasClass('disabled'))
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const promptName = selectedPrompt ? selectedPrompt.prompt : null;
|
|
128
|
+
if (isRequestInProgress || $('#send-button').hasClass('disabled')) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const clientData = {};
|
|
132
|
+
isRequestInProgress = true;
|
|
133
|
+
toggleSendStopButtons(true);
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
try {
|
|
136
|
+
const question = $('#question').val().trim();
|
|
137
|
+
const promptName = selectedPrompt ? selectedPrompt.prompt : null;
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
clientData[field.data_key] = value;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
139
|
+
let displayMessage = question;
|
|
140
|
+
let isEditable = true;
|
|
141
|
+
const clientData = {};
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
if (selectedPrompt) {
|
|
144
|
+
displayMessage = selectedPrompt.description;
|
|
145
|
+
isEditable = false;
|
|
146
|
+
|
|
147
|
+
(selectedPrompt.custom_fields || []).forEach(field => {
|
|
148
|
+
const value = $('#' + field.data_key + '-id').val().trim();
|
|
149
|
+
if (value) {
|
|
150
|
+
clientData[field.data_key] = value;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const paramsString = Object.values(clientData).join(', ');
|
|
155
|
+
if (paramsString) { displayMessage += `: ${paramsString}`; }
|
|
149
156
|
}
|
|
150
|
-
}
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
toggleSendStopButtons(true);
|
|
158
|
+
// Simplificado: Si no hay mensaje, el 'finally' se encargará de limpiar.
|
|
159
|
+
// Simplemente salimos de la función.
|
|
160
|
+
if (!displayMessage) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
158
163
|
|
|
159
|
-
|
|
164
|
+
displayUserMessage(displayMessage, isEditable, question);
|
|
165
|
+
showSpinner();
|
|
166
|
+
resetAllInputs();
|
|
160
167
|
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
const files = window.filePond.getFiles();
|
|
169
|
+
const filesBase64 = await Promise.all(files.map(fileItem => toBase64(fileItem.file)));
|
|
163
170
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
};
|
|
171
|
+
const data = {
|
|
172
|
+
question: question,
|
|
173
|
+
prompt_name: promptName,
|
|
174
|
+
client_data: clientData,
|
|
175
|
+
files: filesBase64.map(f => ({ filename: f.name, content: f.base64 })),
|
|
176
|
+
external_user_id: window.externalUserId
|
|
177
|
+
};
|
|
172
178
|
|
|
173
|
-
try {
|
|
174
179
|
const responseData = await callLLMAPI("/llm_query", data, "POST");
|
|
175
180
|
if (responseData && responseData.answer) {
|
|
176
181
|
const answerSection = $('<div>').addClass('answer-section llm-output').append(responseData.answer);
|
|
177
182
|
displayBotMessage(answerSection);
|
|
178
183
|
}
|
|
179
184
|
} catch (error) {
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
if (error.name === 'AbortError') {
|
|
186
|
+
console.log('Petición abortada por el usuario.');
|
|
187
|
+
|
|
188
|
+
// Usando jQuery estándar para construir el elemento ---
|
|
189
|
+
const icon = $('<i>').addClass('bi bi-stop-circle me-2'); // Icono sin "fill" para un look más ligero
|
|
190
|
+
const textSpan = $('<span>').text('La generación de la respuesta ha sido detenida.');
|
|
191
|
+
|
|
192
|
+
const abortMessage = $('<div>')
|
|
193
|
+
.addClass('system-message')
|
|
194
|
+
.append(icon)
|
|
195
|
+
.append(textSpan);
|
|
196
|
+
|
|
197
|
+
displayBotMessage(abortMessage);
|
|
198
|
+
} else {
|
|
199
|
+
console.error("Error in handleChatMessage:", error);
|
|
200
|
+
const errorSection = $('<div>').addClass('error-section').append('<p>Ocurrió un error al procesar la solicitud.</p>');
|
|
201
|
+
displayBotMessage(errorSection);
|
|
202
|
+
}
|
|
182
203
|
} finally {
|
|
204
|
+
// Este bloque se ejecuta siempre, garantizando que el estado se limpie.
|
|
205
|
+
isRequestInProgress = false;
|
|
183
206
|
hideSpinner();
|
|
184
207
|
toggleSendStopButtons(false);
|
|
185
208
|
updateSendButtonState();
|
|
186
|
-
window.filePond
|
|
209
|
+
if (window.filePond) {
|
|
210
|
+
window.filePond.removeFiles();
|
|
211
|
+
}
|
|
187
212
|
}
|
|
188
213
|
};
|
|
189
214
|
|
|
215
|
+
|
|
190
216
|
/**
|
|
191
217
|
* Resets all inputs to their initial state.
|
|
192
218
|
*/
|
|
@@ -274,16 +300,15 @@ const callLLMAPI = async function(apiPath, data, method, timeoutMs = 500000) {
|
|
|
274
300
|
headers['X-Chat-Token'] = window.sessionJWT;
|
|
275
301
|
}
|
|
276
302
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
303
|
+
abortController = new AbortController();
|
|
304
|
+
const timeoutId = setTimeout(() => abortController.abort(), timeoutMs);
|
|
280
305
|
|
|
281
306
|
try {
|
|
282
307
|
const response = await fetch(url, {
|
|
283
308
|
method: method,
|
|
284
309
|
headers: headers,
|
|
285
310
|
body: JSON.stringify(data),
|
|
286
|
-
signal:
|
|
311
|
+
signal: abortController.signal, // Se usa el signal del controlador global
|
|
287
312
|
credentials: 'include'
|
|
288
313
|
});
|
|
289
314
|
clearTimeout(timeoutId);
|
|
@@ -325,7 +350,8 @@ const displayUserMessage = function(message, isEditable, originalQuestion) {
|
|
|
325
350
|
const editIcon = $('<i>').addClass('p-2 bi bi-pencil-fill edit-icon').attr('title', 'Edit query').on('click', function () {
|
|
326
351
|
$('#question').val(originalQuestion).focus();
|
|
327
352
|
autoResizeTextarea($('#question')[0]);
|
|
328
|
-
|
|
353
|
+
|
|
354
|
+
$('#send-button').removeClass('disabled');
|
|
329
355
|
});
|
|
330
356
|
userMessage.append(editIcon);
|
|
331
357
|
}
|
|
@@ -347,9 +373,8 @@ function displayBotMessage(section) {
|
|
|
347
373
|
* Aborts the current in-progress API request.
|
|
348
374
|
*/
|
|
349
375
|
const abortCurrentRequest = function () {
|
|
350
|
-
if (
|
|
351
|
-
|
|
352
|
-
currentAbortController.abort();
|
|
376
|
+
if (isRequestInProgress && abortController) {
|
|
377
|
+
abortController.abort();
|
|
353
378
|
}
|
|
354
379
|
};
|
|
355
380
|
|
|
@@ -186,6 +186,20 @@
|
|
|
186
186
|
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
/* Estilo para mensajes sutiles del sistema (ej. abortado) */
|
|
190
|
+
.system-message {
|
|
191
|
+
color: var(--brand-secondary-color, #6c757d); /* Usa el color secundario o un gris por defecto */
|
|
192
|
+
font-style: italic;
|
|
193
|
+
font-size: 0.9rem;
|
|
194
|
+
display: flex;
|
|
195
|
+
align-items: center;
|
|
196
|
+
justify-content: start;
|
|
197
|
+
margin: 10px 0;
|
|
198
|
+
padding: 10px;
|
|
199
|
+
opacity: 0.8;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
|
|
189
203
|
#prompt-assistant-collapse .card {
|
|
190
204
|
border-radius: 1.5rem; /* Mismo radio que el chat-input-bar */
|
|
191
205
|
border: 1px solid #dee2e6; /* Mismo borde que el chat-input-bar */
|
|
@@ -233,7 +247,6 @@
|
|
|
233
247
|
|
|
234
248
|
/* 6. Anulación específica para el botón de ENVIAR usando su ID (Máxima Prioridad) */
|
|
235
249
|
#send-button i {
|
|
236
|
-
color: var(--brand-send-button-color); /* Usa la variable de branding */
|
|
237
250
|
font-size: 1.7rem; /* Ligeramente más grande */
|
|
238
251
|
}
|
|
239
252
|
#send-button:hover i {
|
|
@@ -421,4 +434,7 @@
|
|
|
421
434
|
color: #ffc107;
|
|
422
435
|
}
|
|
423
436
|
|
|
437
|
+
#send-button i {
|
|
438
|
+
color: var(--brand-send-button-color);
|
|
439
|
+
}
|
|
424
440
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<div class="d-flex align-items-center">
|
|
27
27
|
<!-- 1. ID de Usuario -->
|
|
28
28
|
<span style="{{ branding.secondary_text_style }}">
|
|
29
|
-
{{ external_user_id or
|
|
29
|
+
{{ external_user_id or user_email }}
|
|
30
30
|
</span>
|
|
31
31
|
|
|
32
32
|
<!-- 2. Separador Vertical -->
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</a>
|
|
44
44
|
|
|
45
45
|
<!-- Icono de cerrar sesión (al final) -->
|
|
46
|
-
{% if
|
|
46
|
+
{% if user_email %}
|
|
47
47
|
<a href="{{ url_for('logout', company_short_name=company_short_name) }}"
|
|
48
48
|
class="ms-3 action-icon-style" title="Cerrar sesión" style="color: {{ branding.header_text_color }} !important;">
|
|
49
49
|
<i class="bi bi-box-arrow-right"></i>
|
|
@@ -164,6 +164,7 @@
|
|
|
164
164
|
window.iatoolkit_base_url = "{{ iatoolkit_base_url }}";
|
|
165
165
|
window.externalUserId = "{{ external_user_id }}";
|
|
166
166
|
window.availablePrompts = {{ prompts.message | tojson }};
|
|
167
|
+
window.sendButtonColor = "{{ branding.send_button_color }}";
|
|
167
168
|
|
|
168
169
|
{% if auth_method == 'jwt' and session_jwt %}
|
|
169
170
|
// Store session JWT if it exists, defined in the same global scope
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<div class="border rounded p-4 shadow-sm bg-light">
|
|
14
14
|
<h4 class="text-muted fw-semibold text-start mb-3">login integrado (IAToolkit)</h4>
|
|
15
15
|
<form id="login-form"
|
|
16
|
-
action="{{ url_for('
|
|
16
|
+
action="{{ url_for('initiate_login', company_short_name=company_short_name) }}"
|
|
17
17
|
method="post">
|
|
18
18
|
<div class="mb-3">
|
|
19
19
|
<label for="company_short_name" class="form-label d-block text-muted">Empresa</label>
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
|
|
113
113
|
// Actualizar action del formulario "Iniciar Sesión"
|
|
114
114
|
if (selectedCompany && selectedCompany.trim() !== '') {
|
|
115
|
-
const loginAction = '/' + selectedCompany + '/
|
|
115
|
+
const loginAction = '/' + selectedCompany + '/initiate_login';
|
|
116
116
|
$('#login-form').attr('action', loginAction); // Actualizamos la URL del form
|
|
117
117
|
} else {
|
|
118
118
|
$('#login-form').attr('action', '#'); // URL genérica si no hay selección
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
$button.prop('disabled', true);
|
|
162
162
|
$spinner.removeClass('d-none');
|
|
163
163
|
|
|
164
|
-
fetch(`/${selectedCompany}/
|
|
164
|
+
fetch(`/${selectedCompany}/initiate_external_chat`, {
|
|
165
165
|
method: 'POST',
|
|
166
166
|
headers: {
|
|
167
167
|
'Content-Type': 'application/json',
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
7
|
import logging
|
|
8
|
-
from flask import request, jsonify, render_template
|
|
8
|
+
from flask import request, jsonify, render_template, url_for, session
|
|
9
9
|
from flask.views import MethodView
|
|
10
10
|
from injector import inject
|
|
11
11
|
from iatoolkit.common.auth import IAuthentication
|
|
@@ -15,6 +15,34 @@ from iatoolkit.services.prompt_manager_service import PromptService
|
|
|
15
15
|
from iatoolkit.services.jwt_service import JWTService
|
|
16
16
|
from iatoolkit.services.branding_service import BrandingService
|
|
17
17
|
|
|
18
|
+
class InitiateExternalChatView(MethodView):
|
|
19
|
+
@inject
|
|
20
|
+
def __init__(self,
|
|
21
|
+
iauthentication: IAuthentication,
|
|
22
|
+
):
|
|
23
|
+
self.iauthentication = iauthentication
|
|
24
|
+
|
|
25
|
+
def post(self, company_short_name: str):
|
|
26
|
+
data = request.get_json()
|
|
27
|
+
if not data or 'external_user_id' not in data:
|
|
28
|
+
return jsonify({"error": "Falta external_user_id"}), 400
|
|
29
|
+
|
|
30
|
+
external_user_id = data['external_user_id']
|
|
31
|
+
|
|
32
|
+
# 1. verify access credentials quickly
|
|
33
|
+
iaut = self.iauthentication.verify(
|
|
34
|
+
company_short_name,
|
|
35
|
+
body_external_user_id=external_user_id
|
|
36
|
+
)
|
|
37
|
+
if not iaut.get("success"):
|
|
38
|
+
return jsonify(iaut), 401
|
|
39
|
+
|
|
40
|
+
# 2. Render the shell page, passing the final data URL and user id
|
|
41
|
+
return render_template("login_shell.html",
|
|
42
|
+
data_source_url=url_for('external_chat_login', company_short_name=company_short_name),
|
|
43
|
+
external_user_id=external_user_id
|
|
44
|
+
)
|
|
45
|
+
|
|
18
46
|
class ExternalChatLoginView(MethodView):
|
|
19
47
|
@inject
|
|
20
48
|
def __init__(self,
|
|
@@ -39,19 +67,12 @@ class ExternalChatLoginView(MethodView):
|
|
|
39
67
|
|
|
40
68
|
external_user_id = data['external_user_id']
|
|
41
69
|
|
|
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
70
|
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
51
71
|
if not company:
|
|
52
72
|
return jsonify({"error": "Empresa no encontrada"}), 404
|
|
53
73
|
|
|
54
74
|
try:
|
|
75
|
+
|
|
55
76
|
# 1. generate a new JWT, our secure access token.
|
|
56
77
|
token = self.jwt_service.generate_chat_jwt(
|
|
57
78
|
company_id=company.id,
|
|
@@ -75,19 +96,15 @@ class ExternalChatLoginView(MethodView):
|
|
|
75
96
|
branding_data = self.branding_service.get_company_branding(company)
|
|
76
97
|
|
|
77
98
|
# 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
99
|
chat_html = render_template("chat.html",
|
|
82
100
|
company_short_name=company_short_name,
|
|
83
|
-
branding=branding_data,
|
|
84
|
-
external_user_id=external_user_id,
|
|
85
|
-
is_mobile=is_mobile,
|
|
86
101
|
auth_method='jwt', # login method is JWT
|
|
87
102
|
session_jwt=token, # pass the token to the front-end
|
|
88
|
-
|
|
103
|
+
external_user_id=external_user_id,
|
|
104
|
+
branding=branding_data,
|
|
89
105
|
prompts=prompts,
|
|
90
|
-
|
|
106
|
+
iatoolkit_base_url=os.getenv('IATOOLKIT_BASE_URL'),
|
|
107
|
+
)
|
|
91
108
|
return chat_html, 200
|
|
92
109
|
|
|
93
110
|
except Exception as e:
|
|
@@ -34,7 +34,7 @@ class HistoryView(MethodView):
|
|
|
34
34
|
return jsonify(iaut), 401
|
|
35
35
|
|
|
36
36
|
external_user_id = data.get("external_user_id")
|
|
37
|
-
local_user_id =
|
|
37
|
+
local_user_id = iaut.get("local_user_id", 0)
|
|
38
38
|
|
|
39
39
|
try:
|
|
40
40
|
response = self.history_service.get_history(
|
|
@@ -0,0 +1,124 @@
|
|
|
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, redirect, render_template, url_for
|
|
8
|
+
from injector import inject
|
|
9
|
+
from iatoolkit.repositories.models import User
|
|
10
|
+
from iatoolkit.services.profile_service import ProfileService
|
|
11
|
+
from iatoolkit.services.prompt_manager_service import PromptService
|
|
12
|
+
from iatoolkit.services.branding_service import BrandingService
|
|
13
|
+
from iatoolkit.services.query_service import QueryService
|
|
14
|
+
import os
|
|
15
|
+
from iatoolkit.common.session_manager import SessionManager
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InitiateLoginView(MethodView):
|
|
19
|
+
"""
|
|
20
|
+
Handles the initial, fast part of the standard login process.
|
|
21
|
+
Authenticates user credentials, sets up the server-side session,
|
|
22
|
+
and immediately returns the loading shell page.
|
|
23
|
+
"""
|
|
24
|
+
@inject
|
|
25
|
+
def __init__(self, profile_service: ProfileService):
|
|
26
|
+
self.profile_service = profile_service
|
|
27
|
+
|
|
28
|
+
def post(self, company_short_name: str):
|
|
29
|
+
# get company info
|
|
30
|
+
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
31
|
+
if not company:
|
|
32
|
+
return render_template('error.html',
|
|
33
|
+
message="Empresa no encontrada"), 404
|
|
34
|
+
|
|
35
|
+
email = request.form.get('email')
|
|
36
|
+
password = request.form.get('password')
|
|
37
|
+
|
|
38
|
+
# authenticate the user
|
|
39
|
+
response = self.profile_service.login(
|
|
40
|
+
company_short_name=company_short_name,
|
|
41
|
+
email=email,
|
|
42
|
+
password=password
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if not response['success']:
|
|
46
|
+
return render_template(
|
|
47
|
+
'login.html',
|
|
48
|
+
company_short_name=company_short_name,
|
|
49
|
+
company=company,
|
|
50
|
+
form_data={
|
|
51
|
+
"email": email,
|
|
52
|
+
"password": password,
|
|
53
|
+
},
|
|
54
|
+
alert_message=response["error"]), 400
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# 3. Render the shell page, passing the URL for the heavy lifting
|
|
58
|
+
# The shell's AJAX call will now be authenticated via the session cookie.
|
|
59
|
+
return render_template(
|
|
60
|
+
"login_shell.html",
|
|
61
|
+
data_source_url=url_for('login', company_short_name=company_short_name),
|
|
62
|
+
external_user_id='' # Pass an empty string, the shell will handle it
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class LoginView(MethodView):
|
|
67
|
+
@inject
|
|
68
|
+
def __init__(self,
|
|
69
|
+
profile_service: ProfileService,
|
|
70
|
+
query_service: QueryService,
|
|
71
|
+
prompt_service: PromptService,
|
|
72
|
+
branding_service: BrandingService):
|
|
73
|
+
self.profile_service = profile_service
|
|
74
|
+
self.query_service = query_service
|
|
75
|
+
self.prompt_service = prompt_service
|
|
76
|
+
self.branding_service = branding_service
|
|
77
|
+
|
|
78
|
+
def get(self, company_short_name: str):
|
|
79
|
+
# get company info
|
|
80
|
+
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
81
|
+
if not company:
|
|
82
|
+
return render_template('error.html', message="Empresa no encontrada"), 404
|
|
83
|
+
|
|
84
|
+
return render_template('login.html',
|
|
85
|
+
company=company,
|
|
86
|
+
company_short_name=company_short_name)
|
|
87
|
+
|
|
88
|
+
def post(self, company_short_name: str):
|
|
89
|
+
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
90
|
+
|
|
91
|
+
# 1. The user is already authenticated by the session cookie set by InitiateLoginView.
|
|
92
|
+
# We just retrieve the user and company IDs from the session.
|
|
93
|
+
user_id = SessionManager.get('user_id')
|
|
94
|
+
user_email = SessionManager.get('user')['email']
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
# 2. init the company/user LLM context.
|
|
98
|
+
self.query_service.llm_init_context(
|
|
99
|
+
company_short_name=company_short_name,
|
|
100
|
+
local_user_id=user_id
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# 3. get the prompt list from backend
|
|
104
|
+
prompts = self.prompt_service.get_user_prompts(company_short_name)
|
|
105
|
+
|
|
106
|
+
# 4. get the branding data
|
|
107
|
+
branding_data = self.branding_service.get_company_branding(company)
|
|
108
|
+
|
|
109
|
+
return render_template("chat.html",
|
|
110
|
+
company_short_name=company_short_name,
|
|
111
|
+
auth_method="Session",
|
|
112
|
+
session_jwt=None, # No JWT in this flow
|
|
113
|
+
user_email=user_email,
|
|
114
|
+
branding=branding_data,
|
|
115
|
+
prompts=prompts,
|
|
116
|
+
iatoolkit_base_url=os.getenv('IATOOLKIT_BASE_URL'),
|
|
117
|
+
), 200
|
|
118
|
+
|
|
119
|
+
except Exception as e:
|
|
120
|
+
return render_template("error.html",
|
|
121
|
+
company=company,
|
|
122
|
+
company_short_name=company_short_name,
|
|
123
|
+
message="Ha ocurrido un error inesperado."), 500
|
|
124
|
+
|
|
@@ -96,7 +96,6 @@ src/iatoolkit/templates/test.html
|
|
|
96
96
|
src/iatoolkit/views/__init__.py
|
|
97
97
|
src/iatoolkit/views/change_password_view.py
|
|
98
98
|
src/iatoolkit/views/chat_token_request_view.py
|
|
99
|
-
src/iatoolkit/views/chat_view.py
|
|
100
99
|
src/iatoolkit/views/download_file_view.py
|
|
101
100
|
src/iatoolkit/views/external_chat_login_view.py
|
|
102
101
|
src/iatoolkit/views/external_login_view.py
|
|
@@ -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,60 +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, redirect, render_template, url_for
|
|
8
|
-
from injector import inject
|
|
9
|
-
from iatoolkit.services.profile_service import ProfileService
|
|
10
|
-
|
|
11
|
-
class LoginView(MethodView):
|
|
12
|
-
@inject
|
|
13
|
-
def __init__(self, profile_service: ProfileService):
|
|
14
|
-
self.profile_service = profile_service
|
|
15
|
-
|
|
16
|
-
def get(self, company_short_name: str):
|
|
17
|
-
# get company info
|
|
18
|
-
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
19
|
-
if not company:
|
|
20
|
-
return render_template('error.html', message="Empresa no encontrada"), 404
|
|
21
|
-
|
|
22
|
-
return render_template('login.html',
|
|
23
|
-
company=company,
|
|
24
|
-
company_short_name=company_short_name)
|
|
25
|
-
|
|
26
|
-
def post(self, company_short_name: str):
|
|
27
|
-
# get company info
|
|
28
|
-
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
29
|
-
if not company:
|
|
30
|
-
return render_template('error.html', message="Empresa no encontrada"), 404
|
|
31
|
-
|
|
32
|
-
email = request.form.get('email')
|
|
33
|
-
try:
|
|
34
|
-
password = request.form.get('password')
|
|
35
|
-
|
|
36
|
-
response = self.profile_service.login(
|
|
37
|
-
company_short_name=company_short_name,
|
|
38
|
-
email=email,
|
|
39
|
-
password=password
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
if "error" in response:
|
|
43
|
-
return render_template(
|
|
44
|
-
'login.html',
|
|
45
|
-
company_short_name=company_short_name,
|
|
46
|
-
company=company,
|
|
47
|
-
form_data={
|
|
48
|
-
"email": email,
|
|
49
|
-
"password": password,
|
|
50
|
-
},
|
|
51
|
-
alert_message=response["error"]), 400
|
|
52
|
-
|
|
53
|
-
return redirect(url_for('chat', company_short_name=company_short_name))
|
|
54
|
-
|
|
55
|
-
except Exception as e:
|
|
56
|
-
return render_template("error.html",
|
|
57
|
-
company=company,
|
|
58
|
-
company_short_name=company_short_name,
|
|
59
|
-
message="Ha ocurrido un error inesperado."), 500
|
|
60
|
-
|
|
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
|
{iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/file_connector_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/google_drive_connector.py
RENAMED
|
File without changes
|
{iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/infra/connectors/local_file_connector.py
RENAMED
|
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
|
|
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
|
{iatoolkit-0.11.0 → iatoolkit-0.12.0}/src/iatoolkit/services/user_session_context_service.py
RENAMED
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|