iatoolkit 0.55.2__tar.gz → 0.66.2__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.
Files changed (151) hide show
  1. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/PKG-INFO +1 -1
  2. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/pyproject.toml +2 -2
  3. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/base_company.py +4 -2
  4. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/common/routes.py +52 -42
  5. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/common/util.py +17 -6
  6. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/iatoolkit.py +50 -21
  7. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/llm_client.py +1 -1
  8. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/openai_adapter.py +1 -1
  9. iatoolkit-0.66.2/src/iatoolkit/locales/en.yaml +144 -0
  10. iatoolkit-0.66.2/src/iatoolkit/locales/es.yaml +140 -0
  11. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/database_manager.py +13 -10
  12. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/models.py +29 -2
  13. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/profile_repo.py +7 -3
  14. iatoolkit-0.66.2/src/iatoolkit/services/auth_service.py +193 -0
  15. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/branding_service.py +28 -22
  16. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/dispatcher_service.py +2 -24
  17. iatoolkit-0.66.2/src/iatoolkit/services/help_content_service.py +30 -0
  18. iatoolkit-0.66.2/src/iatoolkit/services/i18n_service.py +104 -0
  19. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/jwt_service.py +15 -24
  20. iatoolkit-0.66.2/src/iatoolkit/services/language_service.py +77 -0
  21. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/profile_service.py +73 -50
  22. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/query_service.py +1 -8
  23. iatoolkit-0.66.2/src/iatoolkit/services/user_feedback_service.py +103 -0
  24. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/user_session_context_service.py +1 -1
  25. iatoolkit-0.66.2/src/iatoolkit/static/js/chat_feedback_button.js +80 -0
  26. iatoolkit-0.66.2/src/iatoolkit/static/js/chat_help_content.js +124 -0
  27. iatoolkit-0.66.2/src/iatoolkit/static/js/chat_history_button.js +112 -0
  28. iatoolkit-0.66.2/src/iatoolkit/static/js/chat_logout_button.js +36 -0
  29. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/static/js/chat_main.js +62 -173
  30. iatoolkit-0.55.2/src/iatoolkit/static/js/chat_onboarding.js → iatoolkit-0.66.2/src/iatoolkit/static/js/chat_onboarding_button.js +0 -1
  31. iatoolkit-0.66.2/src/iatoolkit/static/js/chat_prompt_manager.js +94 -0
  32. iatoolkit-0.66.2/src/iatoolkit/static/js/chat_reload_button.js +35 -0
  33. iatoolkit-0.66.2/src/iatoolkit/static/styles/chat_iatoolkit.css +592 -0
  34. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/static/styles/chat_modal.css +95 -91
  35. iatoolkit-0.66.2/src/iatoolkit/static/styles/chat_public.css +107 -0
  36. iatoolkit-0.66.2/src/iatoolkit/static/styles/landing_page.css +182 -0
  37. iatoolkit-0.66.2/src/iatoolkit/templates/_company_header.html +20 -0
  38. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/_login_widget.html +12 -11
  39. iatoolkit-0.66.2/src/iatoolkit/templates/base.html +65 -0
  40. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/change_password.html +24 -22
  41. iatoolkit-0.66.2/src/iatoolkit/templates/chat.html +287 -0
  42. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/chat_modals.html +110 -74
  43. iatoolkit-0.66.2/src/iatoolkit/templates/error.html +51 -0
  44. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/forgot_password.html +17 -15
  45. iatoolkit-0.66.2/src/iatoolkit/templates/index.html +145 -0
  46. iatoolkit-0.66.2/src/iatoolkit/templates/login_simulation.html +34 -0
  47. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/onboarding_shell.html +1 -2
  48. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/signup.html +22 -20
  49. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/base_login_view.py +36 -12
  50. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/change_password_view.py +50 -33
  51. iatoolkit-0.66.2/src/iatoolkit/views/external_login_view.py +73 -0
  52. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/file_store_api_view.py +7 -9
  53. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/forgot_password_view.py +21 -19
  54. iatoolkit-0.66.2/src/iatoolkit/views/help_content_api_view.py +54 -0
  55. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/history_api_view.py +16 -12
  56. iatoolkit-0.66.2/src/iatoolkit/views/home_view.py +61 -0
  57. iatoolkit-0.66.2/src/iatoolkit/views/index_view.py +14 -0
  58. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/init_context_api_view.py +26 -15
  59. iatoolkit-0.66.2/src/iatoolkit/views/llmquery_api_view.py +57 -0
  60. iatoolkit-0.66.2/src/iatoolkit/views/login_simulation_view.py +81 -0
  61. iatoolkit-0.66.2/src/iatoolkit/views/login_view.py +153 -0
  62. iatoolkit-0.66.2/src/iatoolkit/views/logout_api_view.py +49 -0
  63. iatoolkit-0.66.2/src/iatoolkit/views/profile_api_view.py +46 -0
  64. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/prompt_api_view.py +8 -8
  65. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/signup_view.py +27 -25
  66. iatoolkit-0.55.2/src/iatoolkit/views/tasks_view.py → iatoolkit-0.66.2/src/iatoolkit/views/tasks_api_view.py +10 -36
  67. iatoolkit-0.66.2/src/iatoolkit/views/tasks_review_api_view.py +55 -0
  68. iatoolkit-0.66.2/src/iatoolkit/views/user_feedback_api_view.py +60 -0
  69. iatoolkit-0.66.2/src/iatoolkit/views/verify_user_view.py +62 -0
  70. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit.egg-info/PKG-INFO +1 -1
  71. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit.egg-info/SOURCES.txt +21 -13
  72. iatoolkit-0.55.2/src/iatoolkit/services/auth_service.py +0 -74
  73. iatoolkit-0.55.2/src/iatoolkit/services/user_feedback_service.py +0 -64
  74. iatoolkit-0.55.2/src/iatoolkit/static/js/chat_feedback.js +0 -115
  75. iatoolkit-0.55.2/src/iatoolkit/static/js/chat_history.js +0 -127
  76. iatoolkit-0.55.2/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -457
  77. iatoolkit-0.55.2/src/iatoolkit/static/styles/chat_info.css +0 -53
  78. iatoolkit-0.55.2/src/iatoolkit/static/styles/landing_page.css +0 -228
  79. iatoolkit-0.55.2/src/iatoolkit/templates/_branding_styles.html +0 -53
  80. iatoolkit-0.55.2/src/iatoolkit/templates/_navbar.html +0 -9
  81. iatoolkit-0.55.2/src/iatoolkit/templates/base.html +0 -48
  82. iatoolkit-0.55.2/src/iatoolkit/templates/chat.html +0 -322
  83. iatoolkit-0.55.2/src/iatoolkit/templates/error.html +0 -15
  84. iatoolkit-0.55.2/src/iatoolkit/templates/header.html +0 -31
  85. iatoolkit-0.55.2/src/iatoolkit/templates/index.html +0 -160
  86. iatoolkit-0.55.2/src/iatoolkit/templates/login_test.html +0 -118
  87. iatoolkit-0.55.2/src/iatoolkit/templates/test.html +0 -9
  88. iatoolkit-0.55.2/src/iatoolkit/views/chat_token_request_view.py +0 -98
  89. iatoolkit-0.55.2/src/iatoolkit/views/external_login_view.py +0 -70
  90. iatoolkit-0.55.2/src/iatoolkit/views/index_view.py +0 -43
  91. iatoolkit-0.55.2/src/iatoolkit/views/llmquery_api_view.py +0 -50
  92. iatoolkit-0.55.2/src/iatoolkit/views/llmquery_web_view.py +0 -38
  93. iatoolkit-0.55.2/src/iatoolkit/views/login_simulation_view.py +0 -60
  94. iatoolkit-0.55.2/src/iatoolkit/views/login_view.py +0 -116
  95. iatoolkit-0.55.2/src/iatoolkit/views/tasks_review_view.py +0 -83
  96. iatoolkit-0.55.2/src/iatoolkit/views/user_feedback_api_view.py +0 -71
  97. iatoolkit-0.55.2/src/iatoolkit/views/verify_user_view.py +0 -55
  98. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/readme.md +0 -0
  99. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/requirements.txt +0 -0
  100. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/setup.cfg +0 -0
  101. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/__init__.py +0 -0
  102. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/cli_commands.py +0 -0
  103. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/common/__init__.py +0 -0
  104. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/common/exceptions.py +0 -0
  105. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/common/session_manager.py +0 -0
  106. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/company_registry.py +0 -0
  107. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/__init__.py +0 -0
  108. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/call_service.py +0 -0
  109. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  110. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  111. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  112. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  113. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  114. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  115. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  116. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/gemini_adapter.py +0 -0
  117. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/google_chat_app.py +0 -0
  118. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/llm_proxy.py +0 -0
  119. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/llm_response.py +0 -0
  120. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/mail_app.py +0 -0
  121. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  122. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/__init__.py +0 -0
  123. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/document_repo.py +0 -0
  124. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  125. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/tasks_repo.py +0 -0
  126. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/repositories/vs_repo.py +0 -0
  127. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/__init__.py +0 -0
  128. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/benchmark_service.py +0 -0
  129. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/document_service.py +0 -0
  130. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/excel_service.py +0 -0
  131. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/file_processor_service.py +0 -0
  132. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/history_service.py +0 -0
  133. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/load_documents_service.py +0 -0
  134. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/mail_service.py +0 -0
  135. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/onboarding_service.py +0 -0
  136. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/prompt_manager_service.py +0 -0
  137. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/search_service.py +0 -0
  138. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/sql_service.py +0 -0
  139. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/services/tasks_service.py +0 -0
  140. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  141. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  142. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/static/styles/llm_output.css +0 -0
  143. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/static/styles/onboarding.css +0 -0
  144. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
  145. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
  146. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
  147. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/templates/about.html +0 -0
  148. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit/views/__init__.py +0 -0
  149. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  150. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/src/iatoolkit.egg-info/requires.txt +0 -0
  151. {iatoolkit-0.55.2 → iatoolkit-0.66.2}/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.55.2
3
+ Version: 0.66.2
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.55.2"
7
+ version = "0.66.2"
8
8
  requires-python = ">=3.12"
9
9
  description = "IAToolkit"
10
10
  readme = "readme.md"
@@ -26,4 +26,4 @@ exclude = ["tests*", "*/tests*"]
26
26
  dependencies = { file = ["requirements.txt"] }
27
27
 
28
28
  [tool.setuptools.package-data]
29
- iatoolkit = ["system_prompts/*.prompt", "templates/**/*", "static/**/*"]
29
+ iatoolkit = ["system_prompts/*.prompt", "templates/**/*", "static/**/*", "locales/*.yaml"]
@@ -29,11 +29,13 @@ class BaseCompany(ABC):
29
29
  def _create_company(self,
30
30
  short_name: str,
31
31
  name: str,
32
+ parameters: dict | None = None,
32
33
  branding: dict | None = None,
33
- onboarding_cards: dict | None = None
34
+ onboarding_cards: dict | None = None,
34
35
  ) -> Company:
35
36
  company_obj = Company(short_name=short_name,
36
37
  name=name,
38
+ parameters=parameters,
37
39
  branding=branding,
38
40
  onboarding_cards=onboarding_cards)
39
41
  self.company = self.profile_repo.create_company(company_obj)
@@ -88,7 +90,7 @@ class BaseCompany(ABC):
88
90
 
89
91
  @abstractmethod
90
92
  # get context specific for this company
91
- def get_user_info(self, user_identifier: str) -> str:
93
+ def get_user_info(self, user_identifier: str) -> dict:
92
94
  raise NotImplementedError("La subclase debe implementar el método get_user_info()")
93
95
 
94
96
  @abstractmethod
@@ -3,17 +3,8 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from flask import render_template, redirect, flash, url_for,send_from_directory, current_app, abort
7
- from iatoolkit.common.session_manager import SessionManager
6
+ from flask import render_template, redirect, url_for,send_from_directory, current_app, abort
8
7
  from flask import jsonify
9
- from iatoolkit.views.history_api_view import HistoryApiView
10
- import os
11
-
12
-
13
- def logout(company_short_name: str):
14
- SessionManager.clear()
15
- flash("Has cerrado sesión correctamente", "info")
16
- return redirect(url_for('index', company_short_name=company_short_name))
17
8
 
18
9
 
19
10
  # this function register all the views
@@ -21,13 +12,10 @@ def register_views(injector, app):
21
12
 
22
13
  from iatoolkit.views.index_view import IndexView
23
14
  from iatoolkit.views.init_context_api_view import InitContextApiView
24
- from iatoolkit.views.llmquery_web_view import LLMQueryWebView
25
15
  from iatoolkit.views.llmquery_api_view import LLMQueryApiView
26
- from iatoolkit.views.tasks_view import TaskView
27
- from iatoolkit.views.tasks_review_view import TaskReviewView
16
+ from iatoolkit.views.tasks_api_view import TaskApiView
17
+ from iatoolkit.views.tasks_review_api_view import TaskReviewApiView
28
18
  from iatoolkit.views.login_simulation_view import LoginSimulationView
29
- from iatoolkit.views.login_view import LoginView, FinalizeContextView
30
- from iatoolkit.views.external_login_view import ExternalLoginView
31
19
  from iatoolkit.views.signup_view import SignupView
32
20
  from iatoolkit.views.verify_user_view import VerifyAccountView
33
21
  from iatoolkit.views.forgot_password_view import ForgotPasswordView
@@ -35,56 +23,78 @@ def register_views(injector, app):
35
23
  from iatoolkit.views.file_store_api_view import FileStoreApiView
36
24
  from iatoolkit.views.user_feedback_api_view import UserFeedbackApiView
37
25
  from iatoolkit.views.prompt_api_view import PromptApiView
38
- from iatoolkit.views.chat_token_request_view import ChatTokenRequestView
26
+ from iatoolkit.views.history_api_view import HistoryApiView
27
+ from iatoolkit.views.help_content_api_view import HelpContentApiView
28
+ from iatoolkit.views.profile_api_view import UserLanguageApiView # <-- Importa la nueva vista
29
+
30
+ from iatoolkit.views.login_view import LoginView, FinalizeContextView
31
+ from iatoolkit.views.external_login_view import ExternalLoginView, RedeemTokenApiView
32
+ from iatoolkit.views.logout_api_view import LogoutApiView
33
+ from iatoolkit.views.home_view import HomeView
39
34
 
40
35
  # iatoolkit home page
41
- app.add_url_rule('/<company_short_name>', view_func=IndexView.as_view('index'))
36
+ app.add_url_rule('/', view_func=IndexView.as_view('index'))
42
37
 
43
- # init (reset) the company context (with api-key)
44
- app.add_url_rule('/<company_short_name>/api/init_context_api',
45
- view_func=InitContextApiView.as_view('init_context_api'))
38
+ # company home view
39
+ app.add_url_rule('/<company_short_name>/home', view_func=HomeView.as_view('home'))
46
40
 
47
- # this functions are for login external users (with api-key)
48
- # only the first one should be used from an external app
41
+ # login for the iatoolkit integrated frontend
42
+ app.add_url_rule('/<company_short_name>/login', view_func=LoginView.as_view('login'))
43
+
44
+ # this is the login for external users
49
45
  app.add_url_rule('/<company_short_name>/external_login',
50
46
  view_func=ExternalLoginView.as_view('external_login'))
51
47
 
52
- # this endpoint is for requesting a chat token for external users
53
- app.add_url_rule('/auth/chat_token',
54
- view_func=ChatTokenRequestView.as_view('chat-token'))
48
+ # this endpoint is called when onboarding_shell finish the context load
49
+ app.add_url_rule(
50
+ '/<company_short_name>/finalize',
51
+ view_func=FinalizeContextView.as_view('finalize_no_token')
52
+ )
55
53
 
56
- # login for the iatoolkit integrated frontend
57
- # this is the main login endpoint for the frontend
58
- app.add_url_rule('/<company_short_name>/login', view_func=LoginView.as_view('login'))
59
- app.add_url_rule('/<company_short_name>/finalize_context_load', view_func=FinalizeContextView.as_view('finalize_context_load'))
54
+ app.add_url_rule(
55
+ '/<company_short_name>/finalize/<token>',
56
+ view_func=FinalizeContextView.as_view('finalize_with_token')
57
+ )
58
+
59
+ app.add_url_rule(
60
+ '/api/profile/language',
61
+ view_func=UserLanguageApiView.as_view('user_language_api')
62
+ )
63
+
64
+ # logout
65
+ app.add_url_rule('/<company_short_name>/api/logout',
66
+ view_func=LogoutApiView.as_view('logout'))
67
+
68
+ # this endpoint is called by the JS for changing the token for a session
69
+ app.add_url_rule('/<string:company_short_name>/api/redeem_token',
70
+ view_func = RedeemTokenApiView.as_view('redeem_token'))
71
+
72
+ # init (reset) the company context
73
+ app.add_url_rule('/<company_short_name>/api/init-context',
74
+ view_func=InitContextApiView.as_view('init-context'),
75
+ methods=['POST', 'OPTIONS'])
60
76
 
61
77
  # register new user, account verification and forgot password
62
78
  app.add_url_rule('/<company_short_name>/signup',view_func=SignupView.as_view('signup'))
63
- app.add_url_rule('/<company_short_name>/logout', 'logout', logout)
64
- app.add_url_rule('/logout', 'logout', logout)
65
79
  app.add_url_rule('/<company_short_name>/verify/<token>', view_func=VerifyAccountView.as_view('verify_account'))
66
80
  app.add_url_rule('/<company_short_name>/forgot-password', view_func=ForgotPasswordView.as_view('forgot_password'))
67
81
  app.add_url_rule('/<company_short_name>/change-password/<token>', view_func=ChangePasswordView.as_view('change_password'))
68
82
 
69
83
  # main chat query, used by the JS in the browser (with credentials)
70
84
  # can be used also for executing iatoolkit prompts
71
- app.add_url_rule('/<company_short_name>/llm_query', view_func=LLMQueryWebView.as_view('llm_query_web'))
72
-
73
- # this is the same function as above, but with api-key
74
85
  app.add_url_rule('/<company_short_name>/api/llm_query', view_func=LLMQueryApiView.as_view('llm_query_api'))
75
86
 
76
- # chat buttons are here on
77
-
78
87
  # open the promt directory
79
88
  app.add_url_rule('/<company_short_name>/api/prompts', view_func=PromptApiView.as_view('prompt'))
80
89
 
81
- # feedback and history
90
+ # toolbar buttons
82
91
  app.add_url_rule('/<company_short_name>/api/feedback', view_func=UserFeedbackApiView.as_view('feedback'))
83
92
  app.add_url_rule('/<company_short_name>/api/history', view_func=HistoryApiView.as_view('history'))
93
+ app.add_url_rule('/<company_short_name>/api/help-content', view_func=HelpContentApiView.as_view('help-content'))
84
94
 
85
95
  # tasks management endpoints: create task, and review answer
86
- app.add_url_rule('/tasks', view_func=TaskView.as_view('tasks'))
87
- app.add_url_rule('/tasks/review/<int:task_id>', view_func=TaskReviewView.as_view('tasks-review'))
96
+ app.add_url_rule('/tasks', view_func=TaskApiView.as_view('tasks'))
97
+ app.add_url_rule('/tasks/review/<int:task_id>', view_func=TaskReviewApiView.as_view('tasks-review'))
88
98
 
89
99
  # this endpoint is for upload documents into the vector store (api-key)
90
100
  app.add_url_rule('/api/load', view_func=FileStoreApiView.as_view('load_api'))
@@ -111,8 +121,8 @@ def register_views(injector, app):
111
121
  except FileNotFoundError:
112
122
  abort(404)
113
123
 
114
- # login testing (old home page)
115
- app.add_url_rule('/login_test/<company_short_name>/<external_user_id>',
124
+ # login testing
125
+ app.add_url_rule('/<company_short_name>/login_test',
116
126
  view_func=LoginSimulationView.as_view('login_test'))
117
127
 
118
128
  app.add_url_rule(
@@ -126,6 +136,6 @@ def register_views(injector, app):
126
136
  # hacer que la raíz '/' vaya al home de iatoolkit
127
137
  @app.route('/')
128
138
  def root_redirect():
129
- return redirect(url_for('index', company_short_name='sample_company'))
139
+ return redirect(url_for('index'))
130
140
 
131
141
 
@@ -21,10 +21,8 @@ class Utility:
21
21
  def __init__(self):
22
22
  self.encryption_key = os.getenv('FERNET_KEY')
23
23
 
24
-
25
24
  def render_prompt_from_template(self,
26
25
  template_pathname: str,
27
- query: str = None,
28
26
  client_data: dict = {},
29
27
  **kwargs) -> str:
30
28
 
@@ -37,8 +35,6 @@ class Utility:
37
35
  env = Environment(loader=FileSystemLoader(template_dir))
38
36
  template = env.get_template(template_file)
39
37
 
40
- kwargs["query"] = query
41
-
42
38
  # add all the keys in client_data to kwargs
43
39
  kwargs.update(client_data)
44
40
 
@@ -53,7 +49,6 @@ class Utility:
53
49
  def render_prompt_from_string(self,
54
50
  template_string: str,
55
51
  searchpath: str | list[str] = None,
56
- query: str = None,
57
52
  client_data: dict = {},
58
53
  **kwargs) -> str:
59
54
  """
@@ -76,7 +71,6 @@ class Utility:
76
71
  env = Environment(loader=loader)
77
72
  template = env.from_string(template_string)
78
73
 
79
- kwargs["query"] = query
80
74
  kwargs.update(client_data)
81
75
 
82
76
  prompt = template.render(**kwargs)
@@ -87,6 +81,23 @@ class Utility:
87
81
  f'No se pudo renderizar el template desde el string, error: {str(e)}') from e
88
82
 
89
83
 
84
+ def get_company_template(self, company_short_name: str, template_name: str) -> str:
85
+ # 1. get the path to the company specific template
86
+ template_path = os.path.join(os.getcwd(), f'companies/{company_short_name}/templates/{template_name}')
87
+ if not os.path.exists(template_path):
88
+ return None
89
+
90
+ # 2. read the file
91
+ try:
92
+ with open(template_path, 'r') as f:
93
+ template_string = f.read()
94
+
95
+ return template_string
96
+ except Exception as e:
97
+ logging.exception(e)
98
+ return None
99
+
100
+
90
101
  def serialize(self, obj):
91
102
  if isinstance(obj, datetime) or isinstance(obj, date):
92
103
  return obj.isoformat()
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from flask import Flask, url_for
6
+ from flask import Flask, url_for, get_flashed_messages
7
7
  from flask_session import Session
8
8
  from flask_injector import FlaskInjector
9
9
  from flask_bcrypt import Bcrypt
@@ -16,10 +16,10 @@ import os
16
16
  from typing import Optional, Dict, Any
17
17
  from iatoolkit.repositories.database_manager import DatabaseManager
18
18
  from werkzeug.middleware.proxy_fix import ProxyFix
19
- from injector import Binder, singleton, Injector
19
+ from injector import Binder, Injector, singleton
20
20
  from importlib.metadata import version as _pkg_version, PackageNotFoundError
21
21
 
22
- IATOOLKIT_VERSION = "0.55.1"
22
+ IATOOLKIT_VERSION = "0.66.2"
23
23
 
24
24
  # global variable for the unique instance of IAToolkit
25
25
  _iatoolkit_instance: Optional['IAToolkit'] = None
@@ -52,7 +52,7 @@ class IAToolkit:
52
52
  self.app = None
53
53
  self.db_manager = None
54
54
  self._injector = None
55
- self.version = IATOOLKIT_VERSION
55
+ self.version = IATOOLKIT_VERSION # default version
56
56
 
57
57
  @classmethod
58
58
  def get_instance(cls) -> 'IAToolkit':
@@ -88,7 +88,7 @@ class IAToolkit:
88
88
  # and other integrations, as views are handled manually.
89
89
  FlaskInjector(app=self.app, injector=self._injector)
90
90
 
91
- # Step 6: initialize dispatcher and registered compaies
91
+ # Step 6: initialize dispatcher and registered companies
92
92
  self._init_dispatcher_and_company_instances()
93
93
 
94
94
  # Step 7: Finalize setup within the application context
@@ -96,13 +96,12 @@ class IAToolkit:
96
96
  self._setup_cors()
97
97
  self._setup_additional_services()
98
98
  self._setup_cli_commands()
99
+ self._setup_request_globals()
99
100
  self._setup_context_processors()
100
101
 
101
102
  # Step 8: define the download_dir for excel's
102
103
  self._setup_download_dir()
103
104
 
104
-
105
-
106
105
  logging.info(f"🎉 IAToolkit v{self.version} inicializado correctamente")
107
106
  self._initialized = True
108
107
  return self.app
@@ -111,6 +110,22 @@ class IAToolkit:
111
110
  # get a value from the config dict or the environment variable
112
111
  return self.config.get(key, os.getenv(key, default))
113
112
 
113
+ def _setup_request_globals(self):
114
+ """
115
+ Configures functions to run before each request to set up
116
+ request-global variables, such as language.
117
+ """
118
+ injector = self._injector
119
+
120
+ @self.app.before_request
121
+ def set_request_language():
122
+ """
123
+ Determines and caches the language for the current request in g.lang.
124
+ """
125
+ from iatoolkit.services.language_service import LanguageService
126
+ language_service = injector.get(LanguageService)
127
+ language_service.get_current_language()
128
+
114
129
  def _setup_logging(self):
115
130
  # Lee el nivel de log desde una variable de entorno, con 'INFO' como valor por defecto.
116
131
  log_level_name = os.getenv('LOG_LEVEL', 'INFO').upper()
@@ -155,10 +170,9 @@ class IAToolkit:
155
170
 
156
171
  self.app.config.update({
157
172
  'VERSION': self.version,
158
- 'SERVER_NAME': domain,
159
173
  'SECRET_KEY': self._get_config_value('FLASK_SECRET_KEY', 'iatoolkit-default-secret'),
160
- 'SESSION_COOKIE_SAMESITE': "None" if is_https else "Lax",
161
- 'SESSION_COOKIE_SECURE': is_https,
174
+ 'SESSION_COOKIE_SAMESITE': "None",
175
+ 'SESSION_COOKIE_SECURE': True,
162
176
  'SESSION_PERMANENT': False,
163
177
  'SESSION_USE_SIGNER': True,
164
178
  'JWT_SECRET_KEY': self._get_config_value('JWT_SECRET_KEY', 'iatoolkit-jwt-secret'),
@@ -227,19 +241,19 @@ class IAToolkit:
227
241
 
228
242
  def _setup_cors(self):
229
243
  """🌐 Configura CORS"""
230
- # Origins por defecto para desarrollo
244
+ from iatoolkit.company_registry import get_company_registry
245
+
246
+ # default CORS origin
231
247
  default_origins = [
232
- "http://localhost:5001",
233
- "http://127.0.0.1:5001",
234
248
  os.getenv('IATOOLKIT_BASE_URL')
235
249
  ]
236
250
 
237
- # Obtener origins adicionales desde configuración/env
251
+ # Iterate through the registered company names
238
252
  extra_origins = []
239
- for i in range(1, 11): # Soporte para CORS_ORIGIN_1 a CORS_ORIGIN_10
240
- origin = self._get_config_value(f'CORS_ORIGIN_{i}')
241
- if origin:
242
- extra_origins.append(origin)
253
+ all_company_instances = get_company_registry().get_all_company_instances()
254
+ for company_name, company_instance in all_company_instances.items():
255
+ cors_origin = company_instance.company.parameters.get('cors_origin', [])
256
+ extra_origins += cors_origin
243
257
 
244
258
  all_origins = default_origins + extra_origins
245
259
 
@@ -254,7 +268,6 @@ class IAToolkit:
254
268
 
255
269
  logging.info(f"✅ CORS configurado para: {all_origins}")
256
270
 
257
-
258
271
  def _configure_core_dependencies(self, binder: Binder):
259
272
  """⚙️ Configures all system dependencies."""
260
273
  try:
@@ -303,6 +316,8 @@ class IAToolkit:
303
316
  from iatoolkit.services.jwt_service import JWTService
304
317
  from iatoolkit.services.dispatcher_service import Dispatcher
305
318
  from iatoolkit.services.branding_service import BrandingService
319
+ from iatoolkit.services.i18n_service import I18nService
320
+ from iatoolkit.services.language_service import LanguageService
306
321
 
307
322
  binder.bind(QueryService, to=QueryService)
308
323
  binder.bind(TaskService, to=TaskService)
@@ -316,6 +331,8 @@ class IAToolkit:
316
331
  binder.bind(JWTService, to=JWTService)
317
332
  binder.bind(Dispatcher, to=Dispatcher)
318
333
  binder.bind(BrandingService, to=BrandingService)
334
+ binder.bind(I18nService, to=I18nService)
335
+ binder.bind(LanguageService, to=LanguageService)
319
336
 
320
337
  def _bind_infrastructure(self, binder: Binder):
321
338
  from iatoolkit.infra.llm_client import llmClient
@@ -325,8 +342,8 @@ class IAToolkit:
325
342
  from iatoolkit.services.auth_service import AuthService
326
343
  from iatoolkit.common.util import Utility
327
344
 
328
- binder.bind(LLMProxy, to=LLMProxy, scope=singleton)
329
- binder.bind(llmClient, to=llmClient, scope=singleton)
345
+ binder.bind(LLMProxy, to=LLMProxy)
346
+ binder.bind(llmClient, to=llmClient)
330
347
  binder.bind(GoogleChatApp, to=GoogleChatApp)
331
348
  binder.bind(MailApp, to=MailApp)
332
349
  binder.bind(AuthService, to=AuthService)
@@ -370,8 +387,18 @@ class IAToolkit:
370
387
  def inject_globals():
371
388
  from iatoolkit.common.session_manager import SessionManager
372
389
  from iatoolkit.services.profile_service import ProfileService
390
+ from iatoolkit.services.i18n_service import I18nService
373
391
 
392
+ # Get services from the injector
374
393
  profile_service = self._injector.get(ProfileService)
394
+ i18n_service = self._injector.get(I18nService)
395
+
396
+ # The 't' function wrapper no longer needs to determine the language itself.
397
+ # It will be automatically handled by the refactored I18nService.
398
+ def translate_for_template(key: str, **kwargs):
399
+ return i18n_service.t(key, **kwargs)
400
+
401
+ # Get user profile if a session exists
375
402
  user_profile = profile_service.get_current_session_info().get('profile', {})
376
403
 
377
404
  return {
@@ -383,6 +410,8 @@ class IAToolkit:
383
410
  'user_is_local': user_profile.get('user_is_local'),
384
411
  'user_email': user_profile.get('user_email'),
385
412
  'iatoolkit_base_url': os.environ.get('IATOOLKIT_BASE_URL', ''),
413
+ 'flashed_messages': get_flashed_messages(with_categories=True),
414
+ 't': translate_for_template
386
415
  }
387
416
 
388
417
  def _get_default_static_folder(self) -> str:
@@ -21,7 +21,7 @@ import tiktoken
21
21
  from typing import Dict, Optional, List
22
22
  from iatoolkit.services.dispatcher_service import Dispatcher
23
23
 
24
- CONTEXT_ERROR_MESSAGE = 'Tu consulta supera el límite de contexto, recarga la página para limpiarlo (esto demora un poco ...)'
24
+ CONTEXT_ERROR_MESSAGE = 'Tu consulta supera el límite de contexto, utiliza el boton de recarga de contexto.'
25
25
 
26
26
  class llmClient:
27
27
  _llm_clients_cache = {} # class attribute, for the clients cache
@@ -55,7 +55,7 @@ class OpenAIAdapter:
55
55
 
56
56
  # En caso de error de contexto
57
57
  if "context_length_exceeded" in str(e):
58
- error_message = 'Tu consulta supera el limite de contexto, sale e ingresa de nuevo a IAToolkit'
58
+ error_message = 'Tu consulta supera el limite de contexto. Reinicia el contexto con el boton de la barra superior.'
59
59
 
60
60
  raise IAToolkitException(IAToolkitException.ErrorType.LLM_ERROR, error_message)
61
61
 
@@ -0,0 +1,144 @@
1
+ # Language: English
2
+ ui:
3
+ login_widget:
4
+ title: "Sign In"
5
+ welcome_message: "Enter your credentials or register to access Sample Company’s AI platform."
6
+ email_placeholder: "Email address"
7
+ password_placeholder: "Password"
8
+ login_button: "Login"
9
+ forgot_password_link: "Forgot your password?"
10
+ no_account_prompt: "Don't have an account?"
11
+ signup_link: "Sign Up"
12
+
13
+ signup:
14
+ title: "Create an Account"
15
+ subtitle: "Start your journey with us today."
16
+ first_name_label: "First Name"
17
+ last_name_label: "Last Name"
18
+ email_label: "Email Address"
19
+ password_label: "Password"
20
+ confirm_password_label: "Confirm Password"
21
+ signup_button: "Create Account"
22
+ already_have_account: "Already have an account?"
23
+ login_link: "Log In"
24
+ disclaimer: "🔒We value your privacy. Your data will be used exclusively for the operation of the platform."
25
+
26
+ forgot_password:
27
+ title: "Recover Password"
28
+ subtitle: "Enter your email address and we will send you a link to reset your password."
29
+ submit_button: "Send Recovery Link"
30
+ back_to_login: "Back to Login"
31
+
32
+ change_password:
33
+ title: "Create New Password"
34
+ subtitle: "You are changing the password for <strong>{email}</strong>."
35
+ temp_code_label: "Temporary Code"
36
+ temp_code_placeholder: "Check your email"
37
+ new_password_label: "New Password"
38
+ password_instructions: "Must contain at least 8 characters, an uppercase letter, a lowercase letter, a number, and a special character."
39
+ confirm_password_label: "Confirm New Password"
40
+ save_button: "Save Password"
41
+ back_to_home: "Back to home"
42
+
43
+ chat:
44
+ welcome_message: "Hello! How can I help you today?"
45
+ input_placeholder: "Type your query here..."
46
+ prompts_available: "Available prompts"
47
+
48
+ tooltips:
49
+ history: "History of my queries"
50
+ reload_context: "Force Context Reload"
51
+ feedback: "Your feedback is very important"
52
+ usage_guide: "Usage Guide"
53
+ onboarding: "How to ask better questions"
54
+ logout: "Log out"
55
+ use_prompt_assistant: "Use Prompt Assistant"
56
+ attach_files: "Attach files"
57
+ view_attached_files: "View attached files"
58
+ send: "Send"
59
+ stop: "Stop"
60
+
61
+ modals:
62
+ files_title: "Uploaded Files"
63
+ feedback_title: "Your Opinion is Important"
64
+ feedback_prompt: "How useful was the assistant's response?"
65
+ feedback_comment_label: "Your feedback helps us improve:"
66
+ feedback_comment_placeholder: "Write your opinion, suggestions, or comments here..."
67
+ history_title: "Query History"
68
+ history_table_date: "Date"
69
+ history_table_query: "Query"
70
+ loading_history: "Loading history..."
71
+ no_history_found: "No query history found."
72
+ help_title: "AI Assistant User Guide"
73
+
74
+ buttons:
75
+ cancel: "Close"
76
+ send: "Send"
77
+ stop: "Stop"
78
+
79
+ errors:
80
+ auth:
81
+ invalid_password: "The provided password is incorrect."
82
+ user_not_found: "A user with that email address was not found."
83
+ invalid_or_expired_token: "Invalid or expired token."
84
+ session_creation_failed: "Could not create user session."
85
+ authentication_required: "Authentication required. No session cookie or API Key provided."
86
+ invalid_api_key: "Invalid or inactive API Key."
87
+ no_user_identifier_api: "No user_identifier provided for API call."
88
+ templates:
89
+ company_not_found: "Company not found."
90
+ home_template_not_found: "The home page template for the company '{company_name}' is not configured."
91
+ template_not_found: "Template not found: '{template_name}'."
92
+
93
+ processing_error: "An error occurred while processing the custom home page template: {error}"
94
+ general:
95
+ unexpected_error: "An unexpected error has occurred. Please contact support."
96
+ unsupported_language: "The selected language is not supported."
97
+ signup:
98
+ company_not_found: "The company {company_name} does not exist."
99
+ incorrect_password_for_existing_user: "The password for the user {email} is incorrect."
100
+ user_already_registered: "The user with email '{email}' already exists in this company."
101
+ password_mismatch: "The passwords do not match. Please try again."
102
+ change_password:
103
+ token_expired: "The password change link has expired. Please request a new one."
104
+ password_mismatch: "The passwords do not match. Please try again."
105
+ invalid_temp_code: "The temporary code is not valid. Please check it or request a new one."
106
+ forgot_password:
107
+ user_not_registered: "The user with email {email} is not registered."
108
+ verification:
109
+ token_expired: "The verification link has expired. Please contact support if you need a new one."
110
+ user_not_found: "The user you are trying to verify does not exist."
111
+ validation:
112
+ password_too_short: "Password must be at least 8 characters long."
113
+ password_no_uppercase: "Password must contain at least one uppercase letter."
114
+ password_no_lowercase: "Password must contain at least one lowercase letter."
115
+ password_no_digit: "Password must contain at least one number."
116
+ password_no_special_char: "Password must contain at least one special character."
117
+
118
+ api_responses:
119
+ context_reloaded_success: "The context has been successfully reloaded."
120
+
121
+ flash_messages:
122
+ password_changed_success: "Your password has been successfully reset. You can now log in."
123
+ login_required: "Please log in to continue."
124
+ signup_success: "Registration successful. Please check your email to verify your account."
125
+ user_associated_success: "Existing user successfully associated with the new company."
126
+ account_verified_success: "Your account has been successfully verified. Welcome!"
127
+ forgot_password_success: "If your email is registered, you will receive a link to reset your password."
128
+
129
+ # Keys specifically for JavaScript
130
+ js_messages:
131
+ feedback_sent_success_title: "Feedback Sent"
132
+ feedback_sent_success_body: "Thank you for your feedback!"
133
+ feedback_sent_error: "Could not send feedback, please try again."
134
+ feedback_rating_error: "Please rate the assistant using the stars."
135
+ feedback_comment_error: "Please write your comment before sending."
136
+ context_reloaded: "Context has been reloaded."
137
+ error_loading_history: "An error occurred while loading the history."
138
+ request_aborted: "The response generation has been stopped."
139
+ processing_error: "An error occurred while processing the request."
140
+ server_comm_error: "Server communication error ({status}). Please try again later."
141
+ network_error: "A network error occurred. Please try again in a few moments."
142
+ unknown_server_error: "Unknown server error."
143
+ loading: "Loading..."
144
+ reload_init: "init reloading context in background..."