iatoolkit 0.12.0__tar.gz → 0.16.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.12.0 → iatoolkit-0.16.0}/PKG-INFO +1 -1
  2. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/pyproject.toml +1 -1
  3. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/base_company.py +8 -2
  4. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/common/routes.py +8 -10
  5. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/iatoolkit.py +8 -0
  6. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/models.py +1 -0
  7. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/profile_repo.py +1 -0
  8. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/branding_service.py +24 -0
  9. iatoolkit-0.16.0/src/iatoolkit/services/onboarding_service.py +43 -0
  10. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +22 -8
  11. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/base.html +3 -3
  12. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/chat.html +5 -5
  13. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/home.html +1 -10
  14. iatoolkit-0.16.0/src/iatoolkit/templates/onboarding_shell.html +167 -0
  15. iatoolkit-0.12.0/src/iatoolkit/views/external_chat_login_view.py → iatoolkit-0.16.0/src/iatoolkit/views/external_login_view.py +62 -20
  16. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/login_view.py +46 -34
  17. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/PKG-INFO +1 -1
  18. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/SOURCES.txt +2 -1
  19. iatoolkit-0.12.0/src/iatoolkit/views/external_login_view.py +0 -40
  20. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/readme.md +0 -0
  21. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/requirements.txt +0 -0
  22. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/setup.cfg +0 -0
  23. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/__init__.py +0 -0
  24. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/cli_commands.py +0 -0
  25. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/common/__init__.py +0 -0
  26. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/common/auth.py +0 -0
  27. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/common/exceptions.py +0 -0
  28. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/common/session_manager.py +0 -0
  29. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/common/util.py +0 -0
  30. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/company_registry.py +0 -0
  31. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/__init__.py +0 -0
  32. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/call_service.py +0 -0
  33. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  34. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  35. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  36. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  37. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  38. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  39. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  40. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/gemini_adapter.py +0 -0
  41. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
  42. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/llm_client.py +0 -0
  43. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
  44. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/llm_response.py +0 -0
  45. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/mail_app.py +0 -0
  46. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/openai_adapter.py +0 -0
  47. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  48. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/__init__.py +0 -0
  49. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/database_manager.py +0 -0
  50. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/document_repo.py +0 -0
  51. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  52. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/tasks_repo.py +0 -0
  53. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
  54. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/__init__.py +0 -0
  55. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/benchmark_service.py +0 -0
  56. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
  57. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/document_service.py +0 -0
  58. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/excel_service.py +0 -0
  59. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/file_processor_service.py +0 -0
  60. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/history_service.py +0 -0
  61. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/jwt_service.py +0 -0
  62. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/load_documents_service.py +0 -0
  63. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/mail_service.py +0 -0
  64. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/profile_service.py +0 -0
  65. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/prompt_manager_service.py +0 -0
  66. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/query_service.py +0 -0
  67. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/search_service.py +0 -0
  68. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/sql_service.py +0 -0
  69. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/tasks_service.py +0 -0
  70. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
  71. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
  72. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/arrow_up.png +0 -0
  73. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
  74. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_clinica.png +0 -0
  75. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_iatoolkit.png +0 -0
  76. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_maxxa.png +0 -0
  77. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_notaria.png +0 -0
  78. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_tarjeta.png +0 -0
  79. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_umayor.png +0 -0
  80. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/upload.png +0 -0
  81. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_feedback.js +0 -0
  82. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  83. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_history.js +0 -0
  84. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_main.js +0 -0
  85. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/chat_info.css +0 -0
  86. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  87. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
  88. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
  89. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
  90. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
  91. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/about.html +0 -0
  92. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/change_password.html +0 -0
  93. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/chat_modals.html +0 -0
  94. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/error.html +0 -0
  95. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/forgot_password.html +0 -0
  96. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/header.html +0 -0
  97. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/login.html +0 -0
  98. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/signup.html +0 -0
  99. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/test.html +0 -0
  100. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/__init__.py +0 -0
  101. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/change_password_view.py +0 -0
  102. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/chat_token_request_view.py +0 -0
  103. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/download_file_view.py +0 -0
  104. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/file_store_view.py +0 -0
  105. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
  106. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/history_view.py +0 -0
  107. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/home_view.py +0 -0
  108. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/llmquery_view.py +0 -0
  109. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/prompt_view.py +0 -0
  110. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/signup_view.py +0 -0
  111. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/tasks_review_view.py +0 -0
  112. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/tasks_view.py +0 -0
  113. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/user_feedback_view.py +0 -0
  114. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit/views/verify_user_view.py +0 -0
  115. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  116. {iatoolkit-0.12.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/requires.txt +0 -0
  117. {iatoolkit-0.12.0 → iatoolkit-0.16.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.12.0
3
+ Version: 0.16.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.12.0"
7
+ version = "0.16.0"
8
8
  requires-python = ">=3.11"
9
9
  description = "IAToolkit"
10
10
  readme = "readme.md"
@@ -26,10 +26,16 @@ class BaseCompany(ABC):
26
26
  self.company = self.profile_repo.get_company_by_short_name(short_name)
27
27
  return self.company
28
28
 
29
- def _create_company(self, short_name: str, name: str, branding: dict | None = None) -> Company:
29
+ def _create_company(self,
30
+ short_name: str,
31
+ name: str,
32
+ branding: dict | None = None,
33
+ onboarding_cards: dict | None = None
34
+ ) -> Company:
30
35
  company_obj = Company(short_name=short_name,
31
36
  name=name,
32
- branding=branding)
37
+ branding=branding,
38
+ onboarding_cards=onboarding_cards)
33
39
  self.company = self.profile_repo.create_company(company_obj)
34
40
  return self.company
35
41
 
@@ -27,7 +27,7 @@ def register_views(injector, app):
27
27
  from iatoolkit.views.tasks_review_view import TaskReviewView
28
28
  from iatoolkit.views.home_view import HomeView
29
29
  from iatoolkit.views.login_view import LoginView, InitiateLoginView
30
- from iatoolkit.views.external_chat_login_view import InitiateExternalChatView, ExternalChatLoginView
30
+ from iatoolkit.views.external_login_view import InitiateExternalChatView, ExternalChatLoginView
31
31
  from iatoolkit.views.signup_view import SignupView
32
32
  from iatoolkit.views.verify_user_view import VerifyAccountView
33
33
  from iatoolkit.views.forgot_password_view import ForgotPasswordView
@@ -36,21 +36,19 @@ def register_views(injector, app):
36
36
  from iatoolkit.views.user_feedback_view import UserFeedbackView
37
37
  from iatoolkit.views.prompt_view import PromptView
38
38
  from iatoolkit.views.chat_token_request_view import ChatTokenRequestView
39
- from iatoolkit.views.external_login_view import ExternalLoginView
40
39
  from iatoolkit.views.download_file_view import DownloadFileView
41
40
 
42
41
  app.add_url_rule('/', view_func=HomeView.as_view('home'))
43
42
 
44
- # front if the company internal portal
45
- app.add_url_rule('/<company_short_name>/chat_login', view_func=ExternalChatLoginView.as_view('external_chat_login'))
46
- app.add_url_rule('/<company_short_name>/external_login/<external_user_id>',
47
- view_func=ExternalLoginView.as_view('external_login'))
43
+ # login for external portals
48
44
  app.add_url_rule('/<company_short_name>/initiate_external_chat',
49
- view_func=InitiateExternalChatView.as_view('initiate_chat_login'))
45
+ view_func=InitiateExternalChatView.as_view('initiate_external_chat'))
46
+ app.add_url_rule('/<company_short_name>/external_login',
47
+ view_func=ExternalChatLoginView.as_view('external_login'))
48
+ app.add_url_rule('/auth/chat_token',
49
+ view_func=ChatTokenRequestView.as_view('chat-token'))
50
50
 
51
- app.add_url_rule('/auth/chat_token', view_func=ChatTokenRequestView.as_view('chat-token'))
52
-
53
- # main pages for the iatoolkit frontend
51
+ # login for the iatoolkit integrated frontend
54
52
  app.add_url_rule('/<company_short_name>/login', view_func=LoginView.as_view('login'))
55
53
  app.add_url_rule('/<company_short_name>/initiate_login', view_func=InitiateLoginView.as_view('initiate_login'))
56
54
 
@@ -144,8 +144,13 @@ class IAToolkit:
144
144
  is_https = self._get_config_value('USE_HTTPS', 'false').lower() == 'true'
145
145
  is_dev = self._get_config_value('FLASK_ENV') == 'development'
146
146
 
147
+ # get the iatoolkit domain
148
+ parsed_url = urlparse(os.getenv('IATOOLKIT_BASE_URL'))
149
+ domain = parsed_url.netloc
150
+
147
151
  self.app.config.update({
148
152
  'VERSION': self.version,
153
+ 'SERVER_NAME': domain,
149
154
  'SECRET_KEY': self._get_config_value('FLASK_SECRET_KEY', 'iatoolkit-default-secret'),
150
155
  'SESSION_COOKIE_SAMESITE': "None" if is_https else "Lax",
151
156
  'SESSION_COOKIE_SECURE': is_https,
@@ -156,6 +161,9 @@ class IAToolkit:
156
161
  'JWT_EXPIRATION_SECONDS_CHAT': int(self._get_config_value('JWT_EXPIRATION_SECONDS_CHAT', 3600))
157
162
  })
158
163
 
164
+ if parsed_url.scheme == 'https':
165
+ self.app.config['PREFERRED_URL_SCHEME'] = 'https'
166
+
159
167
  # Configuración para tokenizers en desarrollo
160
168
  if is_dev:
161
169
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
@@ -58,6 +58,7 @@ class Company(Base):
58
58
  gemini_api_key = Column(String, nullable=True)
59
59
 
60
60
  branding = Column(JSON, nullable=True)
61
+ onboarding_cards = Column(JSON, nullable=True)
61
62
  parameters = Column(JSON, nullable=True, default={})
62
63
  created_at = Column(DateTime, default=datetime.now)
63
64
  allow_jwt = Column(Boolean, default=True, nullable=True)
@@ -74,6 +74,7 @@ class ProfileRepo:
74
74
  if company:
75
75
  company.parameters = new_company.parameters
76
76
  company.branding = new_company.branding
77
+ company.onboarding_cards = new_company.onboarding_cards
77
78
  else:
78
79
  self.session.add(new_company)
79
80
  company = new_company
@@ -44,6 +44,19 @@ class BrandingService:
44
44
  "brand_info_text": "#055160", # Texto azul oscuro
45
45
  "brand_info_border": "#b6effb",
46
46
 
47
+ # Estilos para el Asistente de Prompts ---
48
+ "prompt_assistant_bg": "#f8f9fa",
49
+ "prompt_assistant_border": "#dee2e6",
50
+ "prompt_assistant_icon_color": "#6c757d",
51
+ "prompt_assistant_button_bg": "#FFFFFF",
52
+ "prompt_assistant_button_text": "#495057",
53
+ "prompt_assistant_button_border": "#ced4da",
54
+ "prompt_assistant_dropdown_bg": "#f8f9fa",
55
+ "prompt_assistant_header_bg": "#e9ecef",
56
+ "prompt_assistant_header_text": "#495057",
57
+ "prompt_assistant_item_hover_bg": None, # Usará el primario por defecto
58
+ "prompt_assistant_item_hover_text": None, # Usará el texto sobre primario
59
+
47
60
  # Color para el botón de Enviar ---
48
61
  "send_button_color": "#212529" # Gris oscuro/casi negro por defecto
49
62
  }
@@ -93,6 +106,17 @@ class BrandingService:
93
106
  --brand-info-bg: {final_branding_values['brand_info_bg']};
94
107
  --brand-info-text: {final_branding_values['brand_info_text']};
95
108
  --brand-info-border: {final_branding_values['brand_info_border']};
109
+ --brand-prompt-assistant-bg: {final_branding_values['prompt_assistant_bg']};
110
+ --brand-prompt-assistant-border: {final_branding_values['prompt_assistant_border']};
111
+ --brand-prompt-assistant-icon-color: {final_branding_values['prompt_assistant_icon_color']};
112
+ --brand-prompt-assistant-button-bg: {final_branding_values['prompt_assistant_button_bg']};
113
+ --brand-prompt-assistant-button-text: {final_branding_values['prompt_assistant_button_text']};
114
+ --brand-prompt-assistant-button-border: {final_branding_values['prompt_assistant_button_border']};
115
+ --brand-prompt-assistant-dropdown-bg: {final_branding_values['prompt_assistant_dropdown_bg']};
116
+ --brand-prompt-assistant-header-bg: {final_branding_values['prompt_assistant_header_bg']};
117
+ --brand-prompt-assistant-header-text: {final_branding_values['prompt_assistant_header_text']};
118
+ --brand-prompt-assistant-item-hover-bg: {final_branding_values['prompt_assistant_item_hover_bg'] or final_branding_values['brand_primary_color']};
119
+ --brand-prompt-assistant-item-hover-text: {final_branding_values['prompt_assistant_item_hover_text'] or final_branding_values['brand_text_on_primary']};
96
120
 
97
121
  }}
98
122
  """
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from iatoolkit.repositories.models import Company
7
+ from typing import List, Dict, Any
8
+
9
+
10
+ class OnboardingService:
11
+ """
12
+ Servicio para gestionar las tarjetas de contenido que se muestran
13
+ durante la pantalla de carga (onboarding).
14
+ """
15
+
16
+ def __init__(self):
17
+ """
18
+ Define el conjunto de tarjetas de onboarding por defecto.
19
+ """
20
+ self._default_cards = [
21
+ {'icon': 'fas fa-users', 'title': 'Clientes',
22
+ 'text': 'Conozco en detalle a nuestros clientes: antigüedad, contactos, historial de operaciones.<br><br><strong>Ejemplo:</strong> ¿cuántos clientes nuevos se incorporaron a mi cartera este año?'},
23
+ {'icon': 'fas fa-cubes', 'title': 'Productos',
24
+ 'text': 'Productos: características, condiciones, historial.'},
25
+
26
+ {'icon': 'fas fa-cogs', 'title': 'Personaliza tus Prompts',
27
+ 'text': 'Utiliza la varita mágica y podrás explorar los prompts predefinidos que he preparado para ti.'},
28
+ {'icon': 'fas fa-table', 'title': 'Tablas y Excel',
29
+ 'text': 'Puedes pedirme la respuesta en formato de tablas o excel.<br><br><strong>Ejemplo:</strong> dame una tabla con los 10 certificados más grandes este año.'},
30
+ {'icon': 'fas fa-shield-alt', 'title': 'Seguridad y Confidencialidad',
31
+ 'text': 'Toda tu información es procesada de forma segura y confidencial dentro de nuestro entorno protegido.'}
32
+ ]
33
+
34
+ def get_onboarding_cards(self, company: Company | None) -> List[Dict[str, Any]]:
35
+ """
36
+ Retorna la lista de tarjetas de onboarding para una compañía.
37
+ Si la compañía tiene tarjetas personalizadas, las devuelve.
38
+ De lo contrario, devuelve las tarjetas por defecto.
39
+ """
40
+ if company and company.onboarding_cards:
41
+ return company.onboarding_cards
42
+
43
+ return self._default_cards
@@ -168,7 +168,7 @@
168
168
 
169
169
  /* 1. La caja principal que envuelve toda el área de entrada */
170
170
  .input-area {
171
- background-color: #f8f9fa;
171
+ background-color: var(--brand-prompt-assistant-bg, #f8f9fa);
172
172
  }
173
173
 
174
174
  /* 2. La barra "cápsula" que envuelve el texto y los iconos */
@@ -202,7 +202,7 @@
202
202
 
203
203
  #prompt-assistant-collapse .card {
204
204
  border-radius: 1.5rem; /* Mismo radio que el chat-input-bar */
205
- border: 1px solid #dee2e6; /* Mismo borde que el chat-input-bar */
205
+ border: 1px solid var(--brand-prompt-assistant-border, #dee2e6); /* Mismo borde que el chat-input-bar */
206
206
  box-shadow: none; /* Eliminamos la sombra por defecto del card */
207
207
  }
208
208
 
@@ -241,6 +241,12 @@
241
241
  color: #6c757d;
242
242
  transition: color 0.2s ease-in-out;
243
243
  }
244
+
245
+ /* Anulación específica para el icono de la varita mágica */
246
+ .chat-input-bar a[href="#prompt-assistant-collapse"] i {
247
+ color: var(--brand-prompt-assistant-icon-color, #6c757d);
248
+ }
249
+
244
250
  .chat-input-bar .d-flex a:hover i {
245
251
  color: #343a40;
246
252
  }
@@ -302,8 +308,8 @@
302
308
  }
303
309
 
304
310
  .dropdown-menu-soft {
305
- background-color: #f8f9fa;
306
- border-color: #dee2e6;
311
+ background-color: var(--brand-prompt-assistant-dropdown-bg, #f8f9fa);
312
+ border-color: var(--brand-prompt-assistant-border, #dee2e6);
307
313
  }
308
314
 
309
315
  .dropdown-menu-soft .dropdown-item {
@@ -312,15 +318,15 @@
312
318
 
313
319
  .dropdown-menu-soft .dropdown-item:hover,
314
320
  .dropdown-menu-soft .dropdown-item:focus {
315
- color: #ffffff;
316
- background-color: #495057;
321
+ color: var(--brand-prompt-assistant-item-hover-text, #ffffff);
322
+ background-color: var(--brand-prompt-assistant-item-hover-bg, #495057);
317
323
  padding-left: 1.5rem;
318
324
  transition: all 0.15s ease-in-out;
319
325
  }
320
326
 
321
327
  .dropdown-menu-soft .dropdown-header {
322
- background-color: #495057;
323
- color: #ffffff;
328
+ background-color: var(--brand-prompt-assistant-header-bg, #495057);
329
+ color: var(--brand-prompt-assistant-header-text, #ffffff);
324
330
  font-weight: 600;
325
331
  margin: 4px;
326
332
  padding: 0.4rem 1rem;
@@ -331,6 +337,14 @@
331
337
  border-bottom: none;
332
338
  }
333
339
 
340
+ /* Estilo para el botón principal del asistente de prompts */
341
+ #prompt-select-button {
342
+ background-color: var(--brand-prompt-assistant-button-bg, #FFFFFF);
343
+ color: var(--brand-prompt-assistant-button-text, #495057);
344
+ border-color: var(--brand-prompt-assistant-button-border, #ced4da);
345
+ }
346
+
347
+
334
348
  #clear-selection-button {
335
349
  position: absolute;
336
350
  top: 50%;
@@ -9,9 +9,9 @@
9
9
  <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
10
10
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/filepond/dist/filepond.min.css">
11
11
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
12
- <link rel="stylesheet" href="{{ url_for('static', filename='styles/chat_iatoolkit.css') }}">
13
- <link rel="stylesheet" href="{{ url_for('static', filename='styles/chat_modal.css') }}">
14
- <link rel="stylesheet" href="{{ url_for('static', filename='styles/llm_output.css') }}">
12
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/chat_iatoolkit.css', _external=True) }}">
13
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/chat_modal.css', _external=True) }}">
14
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles/llm_output.css', _external=True) }}">
15
15
  </head>
16
16
  <body class="d-flex flex-column p-3" style="min-height: 100vh;">
17
17
  <main class="d-flex flex-column flex-grow-1">
@@ -44,7 +44,7 @@
44
44
 
45
45
  <!-- Icono de cerrar sesión (al final) -->
46
46
  {% if user_email %}
47
- <a href="{{ url_for('logout', company_short_name=company_short_name) }}"
47
+ <a href="{{ url_for('logout', company_short_name=company_short_name, _external=True) }}"
48
48
  class="ms-3 action-icon-style" title="Cerrar sesión" style="color: {{ branding.header_text_color }} !important;">
49
49
  <i class="bi bi-box-arrow-right"></i>
50
50
  </a>
@@ -173,10 +173,10 @@
173
173
  </script>
174
174
 
175
175
  <!-- Carga de los scripts JS externos después de definir las variables globales -->
176
- <script src="{{ url_for('static', filename='js/chat_filepond.js') }}"></script>
177
- <script src="{{ url_for('static', filename='js/chat_history.js') }}"></script>
178
- <script src="{{ url_for('static', filename='js/chat_feedback.js') }}"></script>
179
- <script src="{{ url_for('static', filename='js/chat_main.js') }}"></script>
176
+ <script src="{{ url_for('static', filename='js/chat_filepond.js', _external=True) }}"></script>
177
+ <script src="{{ url_for('static', filename='js/chat_history.js', _external=True) }}"></script>
178
+ <script src="{{ url_for('static', filename='js/chat_feedback.js', _external=True) }}"></script>
179
+ <script src="{{ url_for('static', filename='js/chat_main.js', _external=True) }}"></script>
180
180
 
181
181
  <script>
182
182
  document.addEventListener('DOMContentLoaded', function() {
@@ -13,7 +13,7 @@
13
13
  <div class="border rounded p-4 shadow-sm bg-light">
14
14
  <h4 class="text-muted fw-semibold text-start mb-3">login integrado (IAToolkit)</h4>
15
15
  <form id="login-form"
16
- action="{{ url_for('initiate_login', company_short_name=company_short_name) }}"
16
+ action="{{ url_for('initiate_login', company_short_name=company_short_name, external_login=True) }}"
17
17
  method="post">
18
18
  <div class="mb-3">
19
19
  <label for="company_short_name" class="form-label d-block text-muted">Empresa</label>
@@ -156,11 +156,6 @@
156
156
  return;
157
157
  }
158
158
 
159
- const $button = $(this);
160
- const $spinner = $button.find('.spinner-border');
161
- $button.prop('disabled', true);
162
- $spinner.removeClass('d-none');
163
-
164
159
  fetch(`/${selectedCompany}/initiate_external_chat`, {
165
160
  method: 'POST',
166
161
  headers: {
@@ -188,10 +183,6 @@
188
183
  .catch(error => {
189
184
  Swal.fire({ icon: 'error', title: 'Error de Inicio de Sesión', text: error.message });
190
185
  })
191
- .finally(() => {
192
- $button.prop('disabled', false);
193
- $spinner.addClass('d-none');
194
- });
195
186
 
196
187
  });
197
188
  });
@@ -0,0 +1,167 @@
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="es">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Iniciando {{ branding.name | default('IAToolkit') }} IA...</title>
7
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
9
+
10
+ <!-- Inyecta las variables CSS de la marca -->
11
+ {% if branding and branding.css_variables %}
12
+ <style>
13
+ {{ branding.css_variables|safe }}
14
+ </style>
15
+ {% endif %}
16
+
17
+ <style>
18
+ /* --- Estilos Generales --- */
19
+ body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
20
+
21
+ #loader-wrapper {
22
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
23
+ background-color: #f4f7f6;
24
+ z-index: 1000;
25
+ display: flex;
26
+ justify-content: center;
27
+ align-items: center;
28
+ flex-direction: column;
29
+ padding: 20px;
30
+ box-sizing: border-box;
31
+ transition: opacity 0.5s ease-in-out;
32
+ }
33
+
34
+ /* --- Estilos de Branding --- */
35
+ #brand-header {
36
+ font-size: 2.5rem;
37
+ font-weight: 700;
38
+ margin: 0 0 30px 0; /* Aumentamos el margen inferior para dar espacio */
39
+ color: var(--brand-secondary-color, #06326B);
40
+ }
41
+ #brand-header .brand-name {
42
+ color: var(--brand-primary-color, #FF5100);
43
+ }
44
+
45
+
46
+ /* --- Estilos de la Tarjeta (Sin cambios) --- */
47
+ #card-container {
48
+ background-color: #fff; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
49
+ padding: 30px; width: 90%; max-width: 450px; text-align: center; transition: opacity 0.3s ease-in-out;
50
+ }
51
+ #card-container .icon { font-size: 40px; color: var(--brand-primary-color, #FF5100); margin-bottom: 15px; }
52
+ #card-container h3 { font-size: 1.25rem; color: #333; margin-bottom: 10px; }
53
+ #card-container p { font-size: 0.95rem; color: #666; line-height: 1.5; min-height: 60px; }
54
+ .card-nav { display: flex; justify-content: space-between; align-items: center; margin-top: 20px; }
55
+ .card-nav button { background-color: var(--brand-secondary-color, #06326B); border: none; color: var(--brand-text-on-secondary, #FFFFFF); border-radius: 50%; width: 40px; height: 40px; cursor: pointer; transition: opacity 0.2s; }
56
+ .card-nav button:hover { opacity: 0.85; }
57
+ #progress-dots { display: flex; gap: 8px; }
58
+ .dot { width: 10px; height: 10px; border-radius: 50%; background-color: #ddd; transition: background-color 0.3s; }
59
+ .dot.active { background-color: var(--brand-primary-color, #FF5100); }
60
+
61
+ /* --- ESTILOS MEJORADOS: SPINNER DE CARGA --- */
62
+ #loading-status { margin-top: 30px; display: flex; align-items: center; gap: 15px; }
63
+ .spinner {
64
+ width: 30px; height: 30px; border: 4px solid rgba(0, 0, 0, 0.1);
65
+ border-top-color: var(--brand-primary-color, #FF5100);
66
+ border-radius: 50%;
67
+ animation: spin 1s linear infinite;
68
+ }
69
+ #loading-status p { font-size: 1rem; font-weight: 500; color: #555; margin: 0; }
70
+ @keyframes spin { to { transform: rotate(360deg); } }
71
+
72
+ /* --- Iframe (Sin cambios) --- */
73
+ #content-container { width: 100%; height: 100%; }
74
+ iframe { width: 100%; height: 100%; border: none; }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <div id="loader-wrapper">
79
+
80
+ <h1 id="brand-header">
81
+ <span class="brand-name">{{ branding.name | default('IAToolkit') }}</span> <span>IA</span>
82
+ </h1>
83
+
84
+ <div id="card-container">
85
+ <div id="card-icon" class="icon"><i class="fas fa-lightbulb"></i></div>
86
+ <h3 id="card-title">Título de la Tarjeta</h3>
87
+ <p id="card-text">Descripción de la tarjeta de capacitación.</p>
88
+ <div class="card-nav">
89
+ <button id="prev-card" aria-label="Anterior"><i class="fas fa-chevron-left"></i></button>
90
+ <div id="progress-dots"></div>
91
+ <button id="next-card" aria-label="Siguiente"><i class="fas fa-chevron-right"></i></button>
92
+ </div>
93
+ </div>
94
+
95
+ <!-- MEJORADO: Texto de estado ahora junto al spinner -->
96
+ <div id="loading-status">
97
+ <div class="spinner"></div>
98
+ <p>Inicializando el contexto de Maxxa para la IA...</p>
99
+ </div>
100
+
101
+ </div>
102
+
103
+ <div id="content-container"></div>
104
+
105
+ <script>
106
+ $(function() {
107
+ const cardsData = {{ onboarding_cards | tojson }};
108
+
109
+ let currentCardIndex = 0, autoRotateInterval;
110
+ const $cardContainer = $('#card-container'), $cardIcon = $('#card-icon'), $cardTitle = $('#card-title'), $cardText = $('#card-text'), $progressDots = $('#progress-dots');
111
+ function displayCard(index) {
112
+ $cardContainer.css('opacity', 0);
113
+ setTimeout(() => {
114
+ const card = cardsData[index];
115
+ $cardIcon.html(`<i class="${card.icon}"></i>`);
116
+ $cardTitle.text(card.title);
117
+ $cardText.html(card.text);
118
+ $progressDots.find('.dot').removeClass('active').eq(index).addClass('active');
119
+ $cardContainer.css('opacity', 1);
120
+ }, 300);
121
+ }
122
+ function startAutoRotate() { autoRotateInterval = setInterval(() => $('#next-card').click(), 5000); }
123
+ cardsData.forEach(() => $progressDots.append('<div class="dot"></div>'));
124
+ displayCard(currentCardIndex);
125
+ startAutoRotate();
126
+ $('#next-card').on('click', function() {
127
+ currentCardIndex = (currentCardIndex + 1) % cardsData.length;
128
+ displayCard(currentCardIndex);
129
+ clearInterval(autoRotateInterval); startAutoRotate();
130
+ });
131
+ $('#prev-card').on('click', function() {
132
+ currentCardIndex = (currentCardIndex - 1 + cardsData.length) % cardsData.length;
133
+ displayCard(currentCardIndex);
134
+ clearInterval(autoRotateInterval); startAutoRotate();
135
+ });
136
+
137
+ const $loader = $('#loader-wrapper');
138
+ const $container = $('#content-container');
139
+
140
+ // URL para el iframe, pasada desde la vista InitiateExternalChatView
141
+ const iframeSrc = "{{ iframe_src_url }}";
142
+
143
+ // Creamos el elemento iframe
144
+ const iframe = document.createElement('iframe');
145
+ iframe.src = iframeSrc;
146
+
147
+ // Estilos para que ocupe toda la pantalla
148
+ iframe.style.width = '100%';
149
+ iframe.style.height = '100%';
150
+ iframe.style.border = 'none';
151
+ iframe.style.display = 'none'; // Empezamos oculto
152
+
153
+ // Evento que se dispara cuando el iframe ha terminado de cargar su contenido
154
+ iframe.onload = function() {
155
+ // Mostramos el iframe
156
+ iframe.style.display = 'block';
157
+ // Ocultamos la animación de carga con una transición suave
158
+ $loader.css('opacity', 0);
159
+ setTimeout(() => $loader.hide(), 500); // Lo eliminamos del DOM después de la transición
160
+ };
161
+
162
+ // Añadimos el iframe al contenedor en el DOM
163
+ $container.append(iframe);
164
+ });
165
+ </script>
166
+ </body>
167
+ </html>