iatoolkit 0.57.0__tar.gz → 0.58.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.

Files changed (117) hide show
  1. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/PKG-INFO +1 -1
  2. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/pyproject.toml +1 -1
  3. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/common/routes.py +2 -8
  4. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/profile_service.py +10 -10
  5. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/query_service.py +0 -3
  6. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/user_session_context_service.py +1 -1
  7. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/js/chat_main.js +2 -2
  8. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/_login_widget.html +2 -1
  9. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/chat.html +3 -63
  10. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/base_login_view.py +11 -29
  11. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/external_login_view.py +20 -4
  12. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/init_context_api_view.py +2 -1
  13. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/llmquery_api_view.py +0 -6
  14. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/login_view.py +6 -1
  15. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit.egg-info/PKG-INFO +1 -1
  16. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit.egg-info/SOURCES.txt +0 -1
  17. iatoolkit-0.57.0/src/iatoolkit/views/llmquery_web_view.py +0 -38
  18. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/readme.md +0 -0
  19. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/requirements.txt +0 -0
  20. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/setup.cfg +0 -0
  21. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/__init__.py +0 -0
  22. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/base_company.py +0 -0
  23. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/cli_commands.py +0 -0
  24. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/common/__init__.py +0 -0
  25. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/common/exceptions.py +0 -0
  26. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/common/session_manager.py +0 -0
  27. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/common/util.py +0 -0
  28. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/company_registry.py +0 -0
  29. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/iatoolkit.py +0 -0
  30. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/__init__.py +0 -0
  31. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/call_service.py +0 -0
  32. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  33. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  34. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  35. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  36. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  37. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  38. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  39. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/gemini_adapter.py +0 -0
  40. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
  41. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/llm_client.py +0 -0
  42. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
  43. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/llm_response.py +0 -0
  44. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/mail_app.py +0 -0
  45. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/openai_adapter.py +0 -0
  46. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  47. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/__init__.py +0 -0
  48. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/database_manager.py +0 -0
  49. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/document_repo.py +0 -0
  50. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  51. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/models.py +0 -0
  52. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/profile_repo.py +0 -0
  53. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/tasks_repo.py +0 -0
  54. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
  55. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/__init__.py +0 -0
  56. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/auth_service.py +0 -0
  57. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/benchmark_service.py +0 -0
  58. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/branding_service.py +0 -0
  59. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
  60. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/document_service.py +0 -0
  61. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/excel_service.py +0 -0
  62. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/file_processor_service.py +0 -0
  63. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/history_service.py +0 -0
  64. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/jwt_service.py +0 -0
  65. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/load_documents_service.py +0 -0
  66. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/mail_service.py +0 -0
  67. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/onboarding_service.py +0 -0
  68. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/prompt_manager_service.py +0 -0
  69. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/search_service.py +0 -0
  70. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/sql_service.py +0 -0
  71. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/tasks_service.py +0 -0
  72. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
  73. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  74. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/js/chat_feedback.js +0 -0
  75. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  76. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/js/chat_history.js +0 -0
  77. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/js/chat_onboarding.js +0 -0
  78. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
  79. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/styles/chat_info.css +0 -0
  80. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  81. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/styles/landing_page.css +0 -0
  82. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
  83. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/static/styles/onboarding.css +0 -0
  84. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
  85. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
  86. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
  87. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/_branding_styles.html +0 -0
  88. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/_navbar.html +0 -0
  89. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/about.html +0 -0
  90. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/base.html +0 -0
  91. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/change_password.html +0 -0
  92. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/chat_modals.html +0 -0
  93. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/error.html +0 -0
  94. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/forgot_password.html +0 -0
  95. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/header.html +0 -0
  96. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/index.html +0 -0
  97. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/login_simulation.html +0 -0
  98. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/onboarding_shell.html +0 -0
  99. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/signup.html +0 -0
  100. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/templates/test.html +0 -0
  101. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/__init__.py +0 -0
  102. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/change_password_view.py +0 -0
  103. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/chat_token_request_view.py +0 -0
  104. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/file_store_api_view.py +0 -0
  105. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
  106. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/history_api_view.py +0 -0
  107. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/index_view.py +0 -0
  108. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/login_simulation_view.py +0 -0
  109. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/prompt_api_view.py +0 -0
  110. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/signup_view.py +0 -0
  111. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/tasks_review_view.py +0 -0
  112. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/tasks_view.py +0 -0
  113. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  114. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit/views/verify_user_view.py +0 -0
  115. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  116. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit.egg-info/requires.txt +0 -0
  117. {iatoolkit-0.57.0 → iatoolkit-0.58.0}/src/iatoolkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.57.0
3
+ Version: 0.58.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "iatoolkit"
7
- version = "0.57.0"
7
+ version = "0.58.0"
8
8
  requires-python = ">=3.12"
9
9
  description = "IAToolkit"
10
10
  readme = "readme.md"
@@ -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/init_context_api',
71
- view_func=InitContextApiView.as_view('init_context_api'))
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
 
@@ -66,16 +66,18 @@ class ProfileService:
66
66
  "extras": {}
67
67
  }
68
68
 
69
- # 2. Call the session creation helper with the pre-built profile.
70
- # user_identifier = str(user.id)
71
- self.create_web_session(company, user_identifier, user_profile)
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 create_external_user_session(self, company: Company, user_identifier: str):
78
+ def create_external_user_profile_context(self, company: Company, user_identifier: str):
77
79
  """
78
- Public method for views to create a web session for an external user.
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.create_web_session(
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 create_web_session(self, company: Company, user_identifier: str, user_profile: dict):
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()
@@ -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 de sesión para un usuario de forma atómica."""
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" required>
17
+ <input type="email" id="email" name="email" class="form-control"
18
+ required value="{{ form_data.email or '' }}">
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 = "{{ redeem_token }}";
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, company_short_name: str, user_identifier: str, company):
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=company_short_name, user_identifier=user_identifier
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.create_external_user_session(company, user_identifier)
40
+ self.profile_service.create_external_user_profile_context(company, user_identifier)
41
41
 
42
- # 3. Delegate the path decision to the centralized logic.
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(company_short_name, user_identifier, company)
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(company_short_name, user_identifier, company)
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.57.0
3
+ Version: 0.58.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -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