iatoolkit 0.57.0__tar.gz → 0.58.1__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.57.0 → iatoolkit-0.58.1}/PKG-INFO +1 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/pyproject.toml +1 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/common/routes.py +2 -8
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/iatoolkit.py +1 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/profile_service.py +10 -10
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/query_service.py +0 -3
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/user_session_context_service.py +1 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/js/chat_main.js +2 -2
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/_login_widget.html +2 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/chat.html +3 -63
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/base_login_view.py +11 -29
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/external_login_view.py +20 -4
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/init_context_api_view.py +2 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/llmquery_api_view.py +0 -6
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/login_view.py +6 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit.egg-info/PKG-INFO +1 -1
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit.egg-info/SOURCES.txt +0 -1
- iatoolkit-0.57.0/src/iatoolkit/views/llmquery_web_view.py +0 -38
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/readme.md +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/requirements.txt +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/setup.cfg +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/base_company.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/cli_commands.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/common/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/common/exceptions.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/common/session_manager.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/common/util.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/company_registry.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/call_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/gemini_adapter.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/google_chat_app.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/llm_client.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/llm_proxy.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/llm_response.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/mail_app.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/openai_adapter.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/redis_session_manager.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/database_manager.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/document_repo.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/models.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/profile_repo.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/tasks_repo.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/repositories/vs_repo.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/auth_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/benchmark_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/branding_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/dispatcher_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/document_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/excel_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/file_processor_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/history_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/jwt_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/load_documents_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/mail_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/onboarding_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/prompt_manager_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/search_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/sql_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/tasks_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/user_feedback_service.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/images/fernando.jpeg +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/js/chat_feedback.js +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/js/chat_filepond.js +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/js/chat_history.js +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/js/chat_onboarding.js +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/styles/chat_info.css +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/styles/chat_modal.css +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/styles/landing_page.css +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/styles/llm_output.css +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/static/styles/onboarding.css +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/_branding_styles.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/_navbar.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/about.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/base.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/change_password.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/chat_modals.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/error.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/forgot_password.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/header.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/index.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/login_simulation.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/onboarding_shell.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/signup.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/templates/test.html +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/__init__.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/change_password_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/chat_token_request_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/file_store_api_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/forgot_password_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/history_api_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/index_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/login_simulation_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/prompt_api_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/signup_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/tasks_review_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/tasks_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/views/verify_user_view.py +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit.egg-info/top_level.txt +0 -0
|
@@ -21,7 +21,6 @@ def register_views(injector, app):
|
|
|
21
21
|
|
|
22
22
|
from iatoolkit.views.index_view import IndexView
|
|
23
23
|
from iatoolkit.views.init_context_api_view import InitContextApiView
|
|
24
|
-
from iatoolkit.views.llmquery_web_view import LLMQueryWebView
|
|
25
24
|
from iatoolkit.views.llmquery_api_view import LLMQueryApiView
|
|
26
25
|
from iatoolkit.views.tasks_view import TaskView
|
|
27
26
|
from iatoolkit.views.tasks_review_view import TaskReviewView
|
|
@@ -67,8 +66,8 @@ def register_views(injector, app):
|
|
|
67
66
|
view_func=ChatTokenRequestView.as_view('chat-token'))
|
|
68
67
|
|
|
69
68
|
# init (reset) the company context (with api-key)
|
|
70
|
-
app.add_url_rule('/<company_short_name>/api/
|
|
71
|
-
view_func=InitContextApiView.as_view('
|
|
69
|
+
app.add_url_rule('/<company_short_name>/api/init-context',
|
|
70
|
+
view_func=InitContextApiView.as_view('init-context'))
|
|
72
71
|
|
|
73
72
|
# register new user, account verification and forgot password
|
|
74
73
|
app.add_url_rule('/<company_short_name>/signup',view_func=SignupView.as_view('signup'))
|
|
@@ -80,13 +79,8 @@ def register_views(injector, app):
|
|
|
80
79
|
|
|
81
80
|
# main chat query, used by the JS in the browser (with credentials)
|
|
82
81
|
# can be used also for executing iatoolkit prompts
|
|
83
|
-
app.add_url_rule('/<company_short_name>/llm_query', view_func=LLMQueryWebView.as_view('llm_query_web'))
|
|
84
|
-
|
|
85
|
-
# this is the same function as above, but with api-key
|
|
86
82
|
app.add_url_rule('/<company_short_name>/api/llm_query', view_func=LLMQueryApiView.as_view('llm_query_api'))
|
|
87
83
|
|
|
88
|
-
# chat buttons are here on
|
|
89
|
-
|
|
90
84
|
# open the promt directory
|
|
91
85
|
app.add_url_rule('/<company_short_name>/api/prompts', view_func=PromptApiView.as_view('prompt'))
|
|
92
86
|
|
|
@@ -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.
|
|
22
|
+
IATOOLKIT_VERSION = "0.58.1"
|
|
23
23
|
|
|
24
24
|
# global variable for the unique instance of IAToolkit
|
|
25
25
|
_iatoolkit_instance: Optional['IAToolkit'] = None
|
|
@@ -66,16 +66,18 @@ class ProfileService:
|
|
|
66
66
|
"extras": {}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
# 2.
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
# 2. create user_profile in context
|
|
70
|
+
self.save_user_profile(company, user_identifier, user_profile)
|
|
71
|
+
|
|
72
|
+
# 3. create the web session
|
|
73
|
+
self.set_session_for_user(company.short_name, user_identifier)
|
|
72
74
|
return {'success': True, "user_identifier": user_identifier, "message": "Login exitoso"}
|
|
73
75
|
except Exception as e:
|
|
74
76
|
return {'success': False, "message": str(e)}
|
|
75
77
|
|
|
76
|
-
def
|
|
78
|
+
def create_external_user_profile_context(self, company: Company, user_identifier: str):
|
|
77
79
|
"""
|
|
78
|
-
Public method for views to create a
|
|
80
|
+
Public method for views to create a user profile context for an external user.
|
|
79
81
|
"""
|
|
80
82
|
# 1. Fetch the external user profile via Dispatcher.
|
|
81
83
|
external_user_profile = self.dispatcher.get_user_info(
|
|
@@ -84,12 +86,12 @@ class ProfileService:
|
|
|
84
86
|
)
|
|
85
87
|
|
|
86
88
|
# 2. Call the session creation helper with external_user_id as user_identifier
|
|
87
|
-
self.
|
|
89
|
+
self.save_user_profile(
|
|
88
90
|
company=company,
|
|
89
91
|
user_identifier=user_identifier,
|
|
90
92
|
user_profile=external_user_profile)
|
|
91
93
|
|
|
92
|
-
def
|
|
94
|
+
def save_user_profile(self, company: Company, user_identifier: str, user_profile: dict):
|
|
93
95
|
"""
|
|
94
96
|
Private helper: Takes a pre-built profile, saves it to Redis, and sets the Flask cookie.
|
|
95
97
|
"""
|
|
@@ -102,10 +104,8 @@ class ProfileService:
|
|
|
102
104
|
# save user_profile in Redis session
|
|
103
105
|
self.session_context.save_profile_data(company.short_name, user_identifier, user_profile)
|
|
104
106
|
|
|
105
|
-
# save a min Flask session cookie for this user
|
|
106
|
-
self.set_session_for_user(company.short_name, user_identifier)
|
|
107
|
-
|
|
108
107
|
def set_session_for_user(self, company_short_name: str, user_identifier:str ):
|
|
108
|
+
# save a min Flask session cookie for this user
|
|
109
109
|
SessionManager.set('company_short_name', company_short_name)
|
|
110
110
|
SessionManager.set('user_identifier', user_identifier)
|
|
111
111
|
|
|
@@ -66,9 +66,6 @@ class QueryService:
|
|
|
66
66
|
|
|
67
67
|
# Get the user profile from the single source of truth.
|
|
68
68
|
user_profile = self.profile_service.get_profile_by_identifier(company_short_name, user_identifier)
|
|
69
|
-
if not user_profile:
|
|
70
|
-
# This might happen if a session exists for a user that was deleted.
|
|
71
|
-
return None, None
|
|
72
69
|
|
|
73
70
|
# render the iatoolkit main system prompt with the company/user information
|
|
74
71
|
system_prompt_template = self.prompt_service.get_system_prompt()
|
{iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/services/user_session_context_service.py
RENAMED
|
@@ -23,7 +23,7 @@ class UserSessionContextService:
|
|
|
23
23
|
return f"session:{company_short_name}/{user_identifier}"
|
|
24
24
|
|
|
25
25
|
def clear_all_context(self, company_short_name: str, user_identifier: str):
|
|
26
|
-
"""Limpia el contexto
|
|
26
|
+
"""Limpia el contexto del LLM en la sesión para un usuario de forma atómica."""
|
|
27
27
|
session_key = self._get_session_key(company_short_name, user_identifier)
|
|
28
28
|
if session_key:
|
|
29
29
|
# RedisSessionManager.remove(session_key)
|
|
@@ -6,7 +6,7 @@ let selectedPrompt = null; // Will hold a lightweight prompt object
|
|
|
6
6
|
|
|
7
7
|
$(document).ready(function () {
|
|
8
8
|
// Gatilla el redeem sin esperar ni manejar respuesta aquí
|
|
9
|
-
if (window.redeemToken
|
|
9
|
+
if (window.redeemToken) {
|
|
10
10
|
const url = `/api/redeem_token`;
|
|
11
11
|
// No await: dejamos que callToolkit maneje todo internamente
|
|
12
12
|
callToolkit(url, {'token': window.redeemToken}, "POST").catch(() => {});
|
|
@@ -183,7 +183,7 @@ const handleChatMessage = async function () {
|
|
|
183
183
|
user_identifier: window.user_identifier
|
|
184
184
|
};
|
|
185
185
|
|
|
186
|
-
const responseData = await callToolkit("/llm_query", data, "POST");
|
|
186
|
+
const responseData = await callToolkit("/api/llm_query", data, "POST");
|
|
187
187
|
if (responseData && responseData.answer) {
|
|
188
188
|
const answerSection = $('<div>').addClass('answer-section llm-output').append(responseData.answer);
|
|
189
189
|
displayBotMessage(answerSection);
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
method="post">
|
|
15
15
|
<div class="mb-3">
|
|
16
16
|
<label for="email" class="form-label d-block">Correo Electrónico</label>
|
|
17
|
-
<input type="email" id="email" name="email" class="form-control"
|
|
17
|
+
<input type="email" id="email" name="email" class="form-control"
|
|
18
|
+
required value="{{ form_data.email if form_data is defined else '' }}">
|
|
18
19
|
</div>
|
|
19
20
|
<div class="mb-3">
|
|
20
21
|
<label for="password" class="form-label d-block">Contraseña</label>
|
|
@@ -183,11 +183,12 @@
|
|
|
183
183
|
// --- Global Configuration from Backend ---
|
|
184
184
|
window.companyShortName = "{{ company_short_name }}";
|
|
185
185
|
window.user_identifier = "{{ user_identifier }}";
|
|
186
|
-
window.redeemToken =
|
|
186
|
+
window.redeemToken = {{ redeem_token | tojson | default('null') }};
|
|
187
187
|
window.iatoolkit_base_url = "{{ iatoolkit_base_url }}";
|
|
188
188
|
window.availablePrompts = {{ prompts.message | tojson }};
|
|
189
189
|
window.onboardingCards = {{ onboarding_cards | tojson }};
|
|
190
190
|
window.sendButtonColor = "{{ branding.send_button_color }}";
|
|
191
|
+
|
|
191
192
|
</script>
|
|
192
193
|
|
|
193
194
|
<!-- Carga de los scripts JS externos después de definir las variables globales -->
|
|
@@ -195,7 +196,7 @@
|
|
|
195
196
|
<script src="{{ url_for('static', filename='js/chat_filepond.js', _external=True) }}"></script>
|
|
196
197
|
<script src="{{ url_for('static', filename='js/chat_history.js', _external=True) }}"></script>
|
|
197
198
|
<script src="{{ url_for('static', filename='js/chat_feedback.js', _external=True) }}"></script>
|
|
198
|
-
<script src="{{ url_for('static', filename='js/chat_main.js', _external=True) }}"></script>
|
|
199
|
+
<script src="{{ url_for('static', filename='js/chat_context_reload.js', _external=True) }}"></script><script src="{{ url_for('static', filename='js/chat_main.js', _external=True) }}"></script>
|
|
199
200
|
|
|
200
201
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
|
|
201
202
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
@@ -223,67 +224,6 @@
|
|
|
223
224
|
})
|
|
224
225
|
});
|
|
225
226
|
|
|
226
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
227
|
-
const reloadButton = document.getElementById('force-reload-button');
|
|
228
|
-
if (!reloadButton) return;
|
|
229
|
-
|
|
230
|
-
const originalIconClass = 'bi bi-arrow-clockwise';
|
|
231
|
-
const spinnerIconClass = 'spinner-border spinner-border-sm';
|
|
232
|
-
|
|
233
|
-
// Configuración de Toastr para que aparezca abajo a la derecha
|
|
234
|
-
toastr.options = { "positionClass": "toast-bottom-right", "preventDuplicates": true };
|
|
235
|
-
|
|
236
|
-
reloadButton.addEventListener('click', function(event) {
|
|
237
|
-
event.preventDefault();
|
|
238
|
-
|
|
239
|
-
if (reloadButton.disabled) return; // Prevenir doble clic
|
|
240
|
-
|
|
241
|
-
// 1. Deshabilitar y mostrar spinner
|
|
242
|
-
reloadButton.disabled = true;
|
|
243
|
-
const icon = reloadButton.querySelector('i');
|
|
244
|
-
icon.className = spinnerIconClass;
|
|
245
|
-
toastr.info('Iniciando recarga de contexto en segundo plano...');
|
|
246
|
-
|
|
247
|
-
// 2. Construir la URL dinámicamente
|
|
248
|
-
const company = window.companyShortName;
|
|
249
|
-
const reloadUrl = `/${company}/api/init_context_api`;
|
|
250
|
-
|
|
251
|
-
// 3. Hacer la llamada AJAX con POST
|
|
252
|
-
fetch(reloadUrl, {
|
|
253
|
-
method: 'POST',
|
|
254
|
-
headers: {
|
|
255
|
-
'Content-Type': 'application/json'
|
|
256
|
-
},
|
|
257
|
-
// Envía un cuerpo vacío o los datos necesarios
|
|
258
|
-
body: JSON.stringify({})
|
|
259
|
-
})
|
|
260
|
-
.then(response => {
|
|
261
|
-
if (!response.ok) {
|
|
262
|
-
return response.json().then(err => {
|
|
263
|
-
throw new Error(err.error_message || `Error del servidor: ${response.status}`);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
return response.json();
|
|
267
|
-
})
|
|
268
|
-
.then(data => {
|
|
269
|
-
if (data.status === 'OK') {
|
|
270
|
-
toastr.success(data.message || 'Contexto recargado exitosamente.');
|
|
271
|
-
} else {
|
|
272
|
-
toastr.error(data.error_message || 'Ocurrió un error desconocido.');
|
|
273
|
-
}
|
|
274
|
-
})
|
|
275
|
-
.catch(error => {
|
|
276
|
-
console.error('Error durante la recarga del contexto:', error);
|
|
277
|
-
toastr.error(error.message || 'Error de red al intentar recargar.');
|
|
278
|
-
})
|
|
279
|
-
.finally(() => {
|
|
280
|
-
// 4. Restaurar el botón
|
|
281
|
-
reloadButton.disabled = false;
|
|
282
|
-
icon.className = originalIconClass;
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
|
|
287
227
|
// Inicialización del modal de onboarding
|
|
288
228
|
document.addEventListener('DOMContentLoaded', function () {
|
|
289
229
|
const btn = document.getElementById('onboarding-button');
|
|
@@ -14,6 +14,7 @@ from iatoolkit.services.branding_service import BrandingService
|
|
|
14
14
|
from iatoolkit.services.onboarding_service import OnboardingService
|
|
15
15
|
from iatoolkit.services.prompt_manager_service import PromptService
|
|
16
16
|
from iatoolkit.services.jwt_service import JWTService
|
|
17
|
+
from iatoolkit.repositories.models import Company
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class BaseLoginView(MethodView):
|
|
@@ -40,44 +41,26 @@ class BaseLoginView(MethodView):
|
|
|
40
41
|
self.query_service = query_service
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
def _handle_login_path(self,
|
|
44
|
+
def _handle_login_path(self,
|
|
45
|
+
company: Company,
|
|
46
|
+
user_identifier: str,
|
|
47
|
+
target_url: str,
|
|
48
|
+
redeem_token: str = None):
|
|
44
49
|
"""
|
|
45
50
|
Centralized logic to decide between the fast path and the slow path.
|
|
46
51
|
"""
|
|
47
|
-
# --- Get the company branding
|
|
52
|
+
# --- Get the company branding and onboarding_cards
|
|
48
53
|
branding_data = self.branding_service.get_company_branding(company)
|
|
54
|
+
onboarding_cards = self.onboarding_service.get_onboarding_cards(company)
|
|
55
|
+
company_short_name = company.short_name
|
|
49
56
|
|
|
50
57
|
# this service decides is the context needs to be rebuilt or not
|
|
51
58
|
prep_result = self.query_service.prepare_context(
|
|
52
|
-
company_short_name=
|
|
59
|
+
company_short_name=company.short_name, user_identifier=user_identifier
|
|
53
60
|
)
|
|
54
61
|
|
|
55
|
-
# generate continuation token for external login
|
|
56
|
-
redeem_token = ''
|
|
57
|
-
if self.__class__.__name__ == 'ExternalLoginView':
|
|
58
|
-
redeem_token = self.jwt_service.generate_chat_jwt(
|
|
59
|
-
company_short_name=company_short_name,
|
|
60
|
-
user_identifier=user_identifier,
|
|
61
|
-
expires_delta_seconds=300
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
if not redeem_token:
|
|
65
|
-
return "Error al generar el redeem_token para login externo.", 500
|
|
66
|
-
|
|
67
62
|
if prep_result.get('rebuild_needed'):
|
|
68
63
|
# --- SLOW PATH: Render the loading shell ---
|
|
69
|
-
onboarding_cards = self.onboarding_service.get_onboarding_cards(company)
|
|
70
|
-
|
|
71
|
-
# callback url to call when the context finish loading
|
|
72
|
-
if redeem_token:
|
|
73
|
-
target_url = url_for('finalize_with_token',
|
|
74
|
-
company_short_name=company_short_name,
|
|
75
|
-
token=redeem_token,
|
|
76
|
-
_external=True)
|
|
77
|
-
else:
|
|
78
|
-
target_url = url_for('finalize_no_token',
|
|
79
|
-
company_short_name=company_short_name,
|
|
80
|
-
_external=True)
|
|
81
64
|
return render_template(
|
|
82
65
|
"onboarding_shell.html",
|
|
83
66
|
iframe_src_url=target_url,
|
|
@@ -87,13 +70,12 @@ class BaseLoginView(MethodView):
|
|
|
87
70
|
else:
|
|
88
71
|
# --- FAST PATH: Render the chat page directly ---
|
|
89
72
|
prompts = self.prompt_service.get_user_prompts(company_short_name)
|
|
90
|
-
onboarding_cards = self.onboarding_service.get_onboarding_cards(company)
|
|
91
73
|
return render_template(
|
|
92
74
|
"chat.html",
|
|
93
75
|
company_short_name=company_short_name,
|
|
94
76
|
user_identifier=user_identifier,
|
|
95
|
-
branding=branding_data,
|
|
96
77
|
prompts=prompts,
|
|
78
|
+
branding=branding_data,
|
|
97
79
|
onboarding_cards=onboarding_cards,
|
|
98
80
|
redeem_token=redeem_token
|
|
99
81
|
)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
7
|
import logging
|
|
8
|
-
from flask import request, jsonify
|
|
8
|
+
from flask import request, jsonify, url_for
|
|
9
9
|
from injector import inject
|
|
10
10
|
from iatoolkit.views.base_login_view import BaseLoginView
|
|
11
11
|
|
|
@@ -37,11 +37,27 @@ class ExternalLoginView(BaseLoginView):
|
|
|
37
37
|
return jsonify(auth_response), 401
|
|
38
38
|
|
|
39
39
|
# 2. Create the external user session.
|
|
40
|
-
self.profile_service.
|
|
40
|
+
self.profile_service.create_external_user_profile_context(company, user_identifier)
|
|
41
41
|
|
|
42
|
-
# 3.
|
|
42
|
+
# 3. create a redeem_token for create session at the end of the process
|
|
43
|
+
redeem_token = self.jwt_service.generate_chat_jwt(
|
|
44
|
+
company_short_name=company_short_name,
|
|
45
|
+
user_identifier=user_identifier,
|
|
46
|
+
expires_delta_seconds=300
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if not redeem_token:
|
|
50
|
+
return jsonify({"error": "Error al generar el redeem_token para login externo."}), 403
|
|
51
|
+
|
|
52
|
+
# 4. define URL to call when slow path is finished
|
|
53
|
+
target_url = url_for('finalize_with_token',
|
|
54
|
+
company_short_name=company_short_name,
|
|
55
|
+
token=redeem_token,
|
|
56
|
+
_external=True)
|
|
57
|
+
|
|
58
|
+
# 5. Delegate the path decision to the centralized logic.
|
|
43
59
|
try:
|
|
44
|
-
return self._handle_login_path(
|
|
60
|
+
return self._handle_login_path(company, user_identifier, target_url, redeem_token)
|
|
45
61
|
except Exception as e:
|
|
46
62
|
logging.exception(f"Error processing external login path for {company_short_name}/{user_identifier}: {e}")
|
|
47
63
|
return jsonify({"error": f"Internal server error while starting chat. {str(e)}"}), 500
|
|
@@ -42,6 +42,7 @@ class InitContextApiView(MethodView):
|
|
|
42
42
|
self.query_service.session_context.clear_all_context(company_short_name, user_identifier)
|
|
43
43
|
logging.info(f"Context for {company_short_name}/{user_identifier} has been cleared.")
|
|
44
44
|
|
|
45
|
+
# LLM context is clean, now we can load it again
|
|
45
46
|
self.query_service.prepare_context(
|
|
46
47
|
company_short_name=company_short_name,
|
|
47
48
|
user_identifier=user_identifier
|
|
@@ -52,7 +53,7 @@ class InitContextApiView(MethodView):
|
|
|
52
53
|
user_identifier=user_identifier
|
|
53
54
|
)
|
|
54
55
|
|
|
55
|
-
logging.info(f"Context for {company_short_name}/{user_identifier} rebuilt successfully.")
|
|
56
|
+
# logging.info(f"Context for {company_short_name}/{user_identifier} rebuilt successfully.")
|
|
56
57
|
|
|
57
58
|
# 3. Respond with JSON, as this is an API endpoint.
|
|
58
59
|
return jsonify({'status': 'OK', 'message': 'Context has been reloaded successfully.'}), 200
|
|
@@ -32,12 +32,6 @@ class LLMQueryApiView(MethodView):
|
|
|
32
32
|
if not data:
|
|
33
33
|
return jsonify({"error": "Invalid JSON body"}), 400
|
|
34
34
|
|
|
35
|
-
# 3. Ensure session state exists for this API user (lazy creation).
|
|
36
|
-
profile = self.profile_service.get_profile_by_identifier(company_short_name, user_identifier)
|
|
37
|
-
if not profile:
|
|
38
|
-
company = self.profile_service.get_company_by_short_name(company_short_name)
|
|
39
|
-
self.profile_service.create_external_user_session(company, user_identifier)
|
|
40
|
-
|
|
41
35
|
# 4. Call the unified query service method.
|
|
42
36
|
result = self.query_service.llm_query(
|
|
43
37
|
company_short_name=company_short_name,
|
|
@@ -51,9 +51,14 @@ class LoginView(BaseLoginView):
|
|
|
51
51
|
|
|
52
52
|
user_identifier = auth_response['user_identifier']
|
|
53
53
|
|
|
54
|
+
# 3. define URL to call when slow path is finished
|
|
55
|
+
target_url = url_for('finalize_no_token',
|
|
56
|
+
company_short_name=company_short_name,
|
|
57
|
+
_external=True)
|
|
58
|
+
|
|
54
59
|
# 2. Delegate the path decision to the centralized logic.
|
|
55
60
|
try:
|
|
56
|
-
return self._handle_login_path(
|
|
61
|
+
return self._handle_login_path(company, user_identifier, target_url)
|
|
57
62
|
except Exception as e:
|
|
58
63
|
return render_template("error.html", company=company, company_short_name=company_short_name,
|
|
59
64
|
message=f"Error processing login path: {str(e)}"), 500
|
|
@@ -104,7 +104,6 @@ src/iatoolkit/views/history_api_view.py
|
|
|
104
104
|
src/iatoolkit/views/index_view.py
|
|
105
105
|
src/iatoolkit/views/init_context_api_view.py
|
|
106
106
|
src/iatoolkit/views/llmquery_api_view.py
|
|
107
|
-
src/iatoolkit/views/llmquery_web_view.py
|
|
108
107
|
src/iatoolkit/views/login_simulation_view.py
|
|
109
108
|
src/iatoolkit/views/login_view.py
|
|
110
109
|
src/iatoolkit/views/prompt_api_view.py
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from flask.views import MethodView
|
|
2
|
-
from flask import request, jsonify
|
|
3
|
-
from injector import inject
|
|
4
|
-
from iatoolkit.services.query_service import QueryService
|
|
5
|
-
from iatoolkit.services.auth_service import AuthService # Use AuthService for session check
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class LLMQueryWebView(MethodView): # Renamed for clarity
|
|
9
|
-
"""
|
|
10
|
-
Web-only endpoint for submitting queries from the chat UI.
|
|
11
|
-
Authenticates via Flask session cookie.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
@inject
|
|
15
|
-
def __init__(self, auth_service: AuthService, query_service: QueryService):
|
|
16
|
-
self.auth_service = auth_service
|
|
17
|
-
self.query_service = query_service
|
|
18
|
-
|
|
19
|
-
def post(self, company_short_name: str):
|
|
20
|
-
# 1. Authenticate the web session request.
|
|
21
|
-
auth_result = self.auth_service.verify()
|
|
22
|
-
if not auth_result.get("success"):
|
|
23
|
-
return jsonify({"error": auth_result.get("error_message")}), auth_result.get("status_code", 401)
|
|
24
|
-
|
|
25
|
-
# 2. Get the guaranteed user_identifier from the auth result.
|
|
26
|
-
user_identifier = auth_result['user_identifier']
|
|
27
|
-
data = request.get_json() or {}
|
|
28
|
-
|
|
29
|
-
# 3. Call the unified query service method.
|
|
30
|
-
result = self.query_service.llm_query(
|
|
31
|
-
company_short_name=company_short_name,
|
|
32
|
-
user_identifier=user_identifier,
|
|
33
|
-
question=data.get('question', ''),
|
|
34
|
-
prompt_name=data.get('prompt_name'),
|
|
35
|
-
client_data=data.get('client_data', {}),
|
|
36
|
-
files=data.get('files', [])
|
|
37
|
-
)
|
|
38
|
-
return jsonify(result)
|
|
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.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/file_connector_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-0.57.0 → iatoolkit-0.58.1}/src/iatoolkit/infra/connectors/google_drive_connector.py
RENAMED
|
File without changes
|
{iatoolkit-0.57.0 → iatoolkit-0.58.1}/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
|
|
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
|
|
File without changes
|