iatoolkit 0.14.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 (116) hide show
  1. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/PKG-INFO +1 -1
  2. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/pyproject.toml +1 -1
  3. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/base_company.py +8 -2
  4. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/common/routes.py +1 -1
  5. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/models.py +1 -0
  6. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/profile_repo.py +1 -0
  7. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/branding_service.py +24 -0
  8. iatoolkit-0.16.0/src/iatoolkit/services/onboarding_service.py +43 -0
  9. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +22 -8
  10. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/home.html +1 -1
  11. iatoolkit-0.14.0/src/iatoolkit/templates/login_shell.html → iatoolkit-0.16.0/src/iatoolkit/templates/onboarding_shell.html +6 -24
  12. iatoolkit-0.14.0/src/iatoolkit/views/login_external_id_view.py → iatoolkit-0.16.0/src/iatoolkit/views/external_login_view.py +44 -18
  13. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/login_view.py +37 -36
  14. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/PKG-INFO +1 -1
  15. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/SOURCES.txt +3 -2
  16. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/readme.md +0 -0
  17. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/requirements.txt +0 -0
  18. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/setup.cfg +0 -0
  19. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/__init__.py +0 -0
  20. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/cli_commands.py +0 -0
  21. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/common/__init__.py +0 -0
  22. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/common/auth.py +0 -0
  23. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/common/exceptions.py +0 -0
  24. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/common/session_manager.py +0 -0
  25. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/common/util.py +0 -0
  26. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/company_registry.py +0 -0
  27. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/iatoolkit.py +0 -0
  28. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/__init__.py +0 -0
  29. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/call_service.py +0 -0
  30. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  31. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  32. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  33. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  34. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  35. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  36. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  37. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/gemini_adapter.py +0 -0
  38. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
  39. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/llm_client.py +0 -0
  40. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
  41. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/llm_response.py +0 -0
  42. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/mail_app.py +0 -0
  43. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/openai_adapter.py +0 -0
  44. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  45. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/__init__.py +0 -0
  46. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/database_manager.py +0 -0
  47. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/document_repo.py +0 -0
  48. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  49. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/tasks_repo.py +0 -0
  50. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
  51. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/__init__.py +0 -0
  52. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/benchmark_service.py +0 -0
  53. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
  54. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/document_service.py +0 -0
  55. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/excel_service.py +0 -0
  56. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/file_processor_service.py +0 -0
  57. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/history_service.py +0 -0
  58. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/jwt_service.py +0 -0
  59. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/load_documents_service.py +0 -0
  60. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/mail_service.py +0 -0
  61. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/profile_service.py +0 -0
  62. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/prompt_manager_service.py +0 -0
  63. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/query_service.py +0 -0
  64. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/search_service.py +0 -0
  65. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/sql_service.py +0 -0
  66. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/tasks_service.py +0 -0
  67. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
  68. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
  69. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/arrow_up.png +0 -0
  70. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
  71. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_clinica.png +0 -0
  72. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_iatoolkit.png +0 -0
  73. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_maxxa.png +0 -0
  74. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_notaria.png +0 -0
  75. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_tarjeta.png +0 -0
  76. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/logo_umayor.png +0 -0
  77. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/images/upload.png +0 -0
  78. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_feedback.js +0 -0
  79. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  80. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_history.js +0 -0
  81. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/js/chat_main.js +0 -0
  82. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/chat_info.css +0 -0
  83. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  84. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
  85. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
  86. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
  87. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
  88. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/about.html +0 -0
  89. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/base.html +0 -0
  90. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/change_password.html +0 -0
  91. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/chat.html +0 -0
  92. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/chat_modals.html +0 -0
  93. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/error.html +0 -0
  94. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/forgot_password.html +0 -0
  95. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/header.html +0 -0
  96. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/login.html +0 -0
  97. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/signup.html +0 -0
  98. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/templates/test.html +0 -0
  99. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/__init__.py +0 -0
  100. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/change_password_view.py +0 -0
  101. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/chat_token_request_view.py +0 -0
  102. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/download_file_view.py +0 -0
  103. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/file_store_view.py +0 -0
  104. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
  105. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/history_view.py +0 -0
  106. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/home_view.py +0 -0
  107. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/llmquery_view.py +0 -0
  108. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/prompt_view.py +0 -0
  109. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/signup_view.py +0 -0
  110. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/tasks_review_view.py +0 -0
  111. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/tasks_view.py +0 -0
  112. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/user_feedback_view.py +0 -0
  113. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit/views/verify_user_view.py +0 -0
  114. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  115. {iatoolkit-0.14.0 → iatoolkit-0.16.0}/src/iatoolkit.egg-info/requires.txt +0 -0
  116. {iatoolkit-0.14.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.14.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.14.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.login_external_id_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
@@ -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%;
@@ -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>
@@ -1,9 +1,9 @@
1
- <!-- templates/iatoolkit/shell.html -->
1
+
2
2
  <!DOCTYPE html>
3
3
  <html lang="es">
4
4
  <head>
5
5
  <meta charset="UTF-8">
6
- <title>Iniciando Maxxa IA...</title>
6
+ <title>Iniciando {{ branding.name | default('IAToolkit') }} IA...</title>
7
7
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
8
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
9
9
 
@@ -78,11 +78,9 @@
78
78
  <div id="loader-wrapper">
79
79
 
80
80
  <h1 id="brand-header">
81
- <span class="brand-name">Maxxa</span><span>IA</span>
81
+ <span class="brand-name">{{ branding.name | default('IAToolkit') }}</span> <span>IA</span>
82
82
  </h1>
83
83
 
84
- <!-- ELIMINADO: El subtítulo de carga que estaba aquí -->
85
-
86
84
  <div id="card-container">
87
85
  <div id="card-icon" class="icon"><i class="fas fa-lightbulb"></i></div>
88
86
  <h3 id="card-title">Título de la Tarjeta</h3>
@@ -106,24 +104,8 @@
106
104
 
107
105
  <script>
108
106
  $(function() {
109
- const cardsData = [
110
- { icon: 'fas fa-users', title: 'Clientes',
111
- text: 'Conozco en detalle a los clientes de Maxxa: antiguedad, contactos, apoderados, historial de operaciones.<br><br><strong>Ejemplo:</strong> cuantos clientes nuevos de garantia se incorporaron a mi cartera este año?' },
112
- { icon: 'fas fa-cubes', title: 'Productos',
113
- text: 'Productos contratados por los clientes: garantias, credito en cuotas, software.<br><br><strong>Ejemplo:</strong> Cuantos clientes de software tengo en cartera?' },
114
- { icon: 'fas fa-exchange-alt', title: 'Operaciones',
115
- text: 'Operaciones de garantia y créditos: tasas, comisiones, acredores, fondos, cobranza, etc.<br><br><strong>Ejemplo:</strong> Dame una tabla con los clientes de mi cartera han emitido mas de 20 garantias este año? columnas: rut, nombre, #garantias, monto, comisión' },
116
- { icon: 'fas fa-landmark', title: 'Chilecompra',
117
- text: 'Historial completo de la participacion en chilecompra de un cliente. <br><br><strong>Ejemplo:</strong> Que porcentaje de garantias FC adjudicadas en los últimos 12 meses por el cliente 1234567-8 las compro en Maxxa.' },
118
- { icon: 'fas fa-comments', title: 'Equipos Comerciales',
119
- text: 'Conozco los equipos comerciales de crédito y garantia. <br><br><strong>Ejemplo:</strong> dime las 10 licitaciones mas grandes que han ganado clientes de mi cartera este año.' },
120
- { icon: 'fas fa-cogs', title: 'Personaliza tus Prompts',
121
- text: 'Utiliza la varita magica y podras explorar los prompts predefinidos que he preparado para ti.' },
122
- { icon: 'fas fa-table', title: 'Tablas y Excel',
123
- text: 'Puedes pedirme la respuesta en formato de tablas o excel. <br><br><strong>Ejemplo:</strong> dame una tabla con los 10 certificados mas grande este año, columnas: rut, cliente, fecha, monto, tasa, comision, acreedor...' },
124
- { icon: 'fas fa-shield-alt', title: 'Seguridad y Confidencialidad',
125
- text: 'Toda tu información es procesada de forma segura y confidencial dentro de nuestro entorno protegido.' }
126
- ];
107
+ const cardsData = {{ onboarding_cards | tojson }};
108
+
127
109
  let currentCardIndex = 0, autoRotateInterval;
128
110
  const $cardContainer = $('#card-container'), $cardIcon = $('#card-icon'), $cardTitle = $('#card-title'), $cardText = $('#card-text'), $progressDots = $('#progress-dots');
129
111
  function displayCard(index) {
@@ -152,7 +134,7 @@
152
134
  clearInterval(autoRotateInterval); startAutoRotate();
153
135
  });
154
136
 
155
- const $loader = $('#loader-wrapper');
137
+ const $loader = $('#loader-wrapper');
156
138
  const $container = $('#content-container');
157
139
 
158
140
  // URL para el iframe, pasada desde la vista InitiateExternalChatView
@@ -14,17 +14,24 @@ from iatoolkit.services.query_service import QueryService
14
14
  from iatoolkit.services.prompt_manager_service import PromptService
15
15
  from iatoolkit.services.jwt_service import JWTService
16
16
  from iatoolkit.services.branding_service import BrandingService
17
+ from iatoolkit.services.onboarding_service import OnboardingService
18
+ from iatoolkit.services.jwt_service import JWTService
19
+
17
20
 
18
21
  class InitiateExternalChatView(MethodView):
19
22
  @inject
20
23
  def __init__(self,
21
24
  iauthentication: IAuthentication,
22
25
  branding_service: BrandingService,
23
- profile_service: ProfileService
26
+ profile_service: ProfileService,
27
+ onboarding_service: OnboardingService,
28
+ jwt_service: JWTService
24
29
  ):
25
30
  self.iauthentication = iauthentication
26
31
  self.branding_service = branding_service
27
32
  self.profile_service = profile_service
33
+ self.onboarding_service = onboarding_service
34
+ self.jwt_service = jwt_service
28
35
 
29
36
  def post(self, company_short_name: str):
30
37
  data = request.get_json()
@@ -45,19 +52,29 @@ class InitiateExternalChatView(MethodView):
45
52
  if not iaut.get("success"):
46
53
  return jsonify(iaut), 401
47
54
 
48
- # 2. Get branding data for the shell page
55
+ # 2. Generate a short-lived initiation token.
56
+ initiation_token = self.jwt_service.generate_chat_jwt(
57
+ company_id=company.id,
58
+ company_short_name=company.short_name,
59
+ external_user_id=external_user_id,
60
+ expires_delta_seconds=180
61
+ )
62
+
63
+ # 2. Get branding and onboarding data for the shell page
49
64
  branding_data = self.branding_service.get_company_branding(company)
65
+ onboarding_cards = self.onboarding_service.get_onboarding_cards(company)
50
66
 
51
- # Generamos la URL para el SRC del iframe, añadiendo el usuario como un query parameter.
52
- target_url = url_for('external_login', # Apunta a la vista del chat
67
+ # 4. Generate the URL for the iframe's SRC, now with the secure token.
68
+ target_url = url_for('external_login',
53
69
  company_short_name=company_short_name,
54
- external_user_id=external_user_id, # Se añadirá como ?external_user_id=...
70
+ init_token=initiation_token,
55
71
  _external=True)
56
72
 
57
- # Renderizamos el shell para un iframe.
58
- return render_template("login_shell.html",
59
- iframe_src_url=target_url, # Le cambiamos el nombre para más claridad
60
- branding=branding_data
73
+ # 5. Render the shell.
74
+ return render_template("onboarding_shell.html",
75
+ iframe_src_url=target_url,
76
+ branding=branding_data,
77
+ onboarding_cards=onboarding_cards
61
78
  )
62
79
 
63
80
  class ExternalChatLoginView(MethodView):
@@ -78,10 +95,20 @@ class ExternalChatLoginView(MethodView):
78
95
  self.branding_service = branding_service
79
96
 
80
97
  def get(self, company_short_name: str):
81
- # Leemos el user_id desde los parámetros de la URL (?external_user_id=...)
82
- external_user_id = request.args.get('external_user_id')
98
+ # 1. Validate the initiation token from the URL
99
+ init_token = request.args.get('init_token')
100
+ if not init_token:
101
+ return "Falta el token de iniciación.", 401
102
+
103
+ # Reutilizamos el validador de JWT, ya que el token tiene la misma estructura
104
+ payload = self.jwt_service.validate_chat_jwt(init_token, company_short_name)
105
+ if not payload:
106
+ return "Token de iniciación inválido o expirado.", 401
107
+
108
+ # 2. Extract user ID securely from the validated token
109
+ external_user_id = payload.get('external_user_id')
83
110
  if not external_user_id:
84
- return "Falta el parámetro external_user_id en la URL", 400
111
+ return "Token con formato incorrecto.", 400
85
112
 
86
113
  company = self.profile_service.get_company_by_short_name(company_short_name)
87
114
  if not company:
@@ -89,8 +116,7 @@ class ExternalChatLoginView(MethodView):
89
116
  return jsonify({"error": "Empresa no encontrada"}), 404
90
117
 
91
118
  try:
92
-
93
- # 1. generate a new JWT, our secure access token.
119
+ # 3. Generate a new long-lived session JWT.
94
120
  token = self.jwt_service.generate_chat_jwt(
95
121
  company_id=company.id,
96
122
  company_short_name=company.short_name,
@@ -100,19 +126,19 @@ class ExternalChatLoginView(MethodView):
100
126
  if not token:
101
127
  raise Exception("No se pudo generar el token de sesión (JWT).")
102
128
 
103
- # 2. init the company/user LLM context.
129
+ # 4. Init the company/user LLM context.
104
130
  self.query_service.llm_init_context(
105
131
  company_short_name=company_short_name,
106
132
  external_user_id=external_user_id
107
133
  )
108
134
 
109
- # 3. get the prompt list from backend
135
+ # 5. get the prompt list from backend
110
136
  prompts = self.prompt_service.get_user_prompts(company_short_name)
111
137
 
112
- # 4. get the branding data
138
+ # 6. get the branding data
113
139
  branding_data = self.branding_service.get_company_branding(company)
114
140
 
115
- # 5. render the chat page with the company/user information.
141
+ # 7. render the chat page with the company/user information.
116
142
  return render_template("chat.html",
117
143
  company_short_name=company_short_name,
118
144
  auth_method='jwt',
@@ -6,14 +6,13 @@
6
6
  from flask.views import MethodView
7
7
  from flask import request, redirect, render_template, url_for
8
8
  from injector import inject
9
- from iatoolkit.repositories.models import User
10
9
  from iatoolkit.services.profile_service import ProfileService
11
10
  from iatoolkit.services.prompt_manager_service import PromptService
12
- from iatoolkit.services.branding_service import BrandingService
13
11
  from iatoolkit.services.query_service import QueryService
14
12
  import os
15
13
  from iatoolkit.common.session_manager import SessionManager
16
14
  from iatoolkit.services.branding_service import BrandingService
15
+ from iatoolkit.services.onboarding_service import OnboardingService
17
16
 
18
17
  class InitiateLoginView(MethodView):
19
18
  """
@@ -24,9 +23,11 @@ class InitiateLoginView(MethodView):
24
23
  @inject
25
24
  def __init__(self,
26
25
  profile_service: ProfileService,
27
- branding_service: BrandingService,):
26
+ branding_service: BrandingService,
27
+ onboarding_service: OnboardingService):
28
28
  self.profile_service = profile_service
29
29
  self.branding_service = branding_service
30
+ self.onboarding_service = onboarding_service
30
31
 
31
32
  def post(self, company_short_name: str):
32
33
  # get company info
@@ -56,18 +57,22 @@ class InitiateLoginView(MethodView):
56
57
  },
57
58
  alert_message=response["error"]), 400
58
59
 
59
- # 2. Get branding data for the shell page
60
+ # 2. Get branding and onboarding data for the shell page
60
61
  branding_data = self.branding_service.get_company_branding(company)
62
+ onboarding_cards = self.onboarding_service.get_onboarding_cards(company)
63
+
64
+ target_url = url_for('login',
65
+ company_short_name=company_short_name,
66
+ _external=True)
61
67
 
62
68
  # 3. Render the shell page, passing the URL for the heavy lifting
63
69
  # The shell's AJAX call will now be authenticated via the session cookie.
64
70
  return render_template(
65
- "login_shell.html",
66
- data_source_url=url_for('login',
67
- company_short_name=company_short_name,
68
- _external=True),
71
+ "onboarding_shell.html",
72
+ iframe_src_url=target_url,
69
73
  external_user_id='',
70
74
  branding=branding_data,
75
+ onboarding_cards=onboarding_cards
71
76
  )
72
77
 
73
78
 
@@ -84,52 +89,48 @@ class LoginView(MethodView):
84
89
  self.branding_service = branding_service
85
90
 
86
91
  def get(self, company_short_name: str):
87
- # get company info
88
- company = self.profile_service.get_company_by_short_name(company_short_name)
89
- if not company:
90
- return render_template('error.html', message="Empresa no encontrada"), 404
91
-
92
- return render_template('login.html',
93
- company=company,
94
- company_short_name=company_short_name)
95
-
96
- def post(self, company_short_name: str):
97
- company = self.profile_service.get_company_by_short_name(company_short_name)
98
-
99
- # 1. The user is already authenticated by the session cookie set by InitiateLoginView.
100
- # We just retrieve the user and company IDs from the session.
92
+ """
93
+ Handles the heavy-lifting part of the login, triggered by the iframe.
94
+ The user is already authenticated via the session cookie.
95
+ """
96
+ # 1. Retrieve user and company info from the session.
101
97
  user_id = SessionManager.get('user_id')
102
98
  if not user_id:
103
- return render_template('error.html', message="Usuario no encontrado"), 404
99
+ # This can happen if the session expires or is invalid.
100
+ # Redirecting to home is a safe fallback.
101
+ return redirect(url_for('home', company_short_name=company_short_name))
104
102
 
105
103
  user_email = SessionManager.get('user')['email']
104
+ company = self.profile_service.get_company_by_short_name(company_short_name)
105
+ if not company:
106
+ return render_template('error.html', message="Empresa no encontrada"), 404
106
107
 
107
108
  try:
108
- # 2. init the company/user LLM context.
109
+ # 2. Init the company/user LLM context (the long-running task).
109
110
  self.query_service.llm_init_context(
110
111
  company_short_name=company_short_name,
111
112
  local_user_id=user_id
112
113
  )
113
114
 
114
- # 3. get the prompt list from backend
115
+ # 3. Get the prompt list from backend.
115
116
  prompts = self.prompt_service.get_user_prompts(company_short_name)
116
117
 
117
- # 4. get the branding data
118
+ # 4. Get the branding data.
118
119
  branding_data = self.branding_service.get_company_branding(company)
119
120
 
121
+ # 5. Render the final chat page.
120
122
  return render_template("chat.html",
121
- company_short_name=company_short_name,
122
- auth_method="Session",
123
- session_jwt=None, # No JWT in this flow
124
- user_email=user_email,
125
- branding=branding_data,
126
- prompts=prompts,
127
- iatoolkit_base_url=os.getenv('IATOOLKIT_BASE_URL'),
128
- ), 200
123
+ company_short_name=company_short_name,
124
+ auth_method="Session",
125
+ session_jwt=None, # No JWT in this flow
126
+ user_email=user_email,
127
+ branding=branding_data,
128
+ prompts=prompts,
129
+ iatoolkit_base_url=os.getenv('IATOOLKIT_BASE_URL'),
130
+ ), 200
129
131
 
130
132
  except Exception as e:
131
133
  return render_template("error.html",
132
134
  company=company,
133
135
  company_short_name=company_short_name,
134
- message="Ha ocurrido un error inesperado."), 500
135
-
136
+ message="Ha ocurrido un error inesperado."), 500
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.14.0
3
+ Version: 0.16.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -53,6 +53,7 @@ src/iatoolkit/services/history_service.py
53
53
  src/iatoolkit/services/jwt_service.py
54
54
  src/iatoolkit/services/load_documents_service.py
55
55
  src/iatoolkit/services/mail_service.py
56
+ src/iatoolkit/services/onboarding_service.py
56
57
  src/iatoolkit/services/profile_service.py
57
58
  src/iatoolkit/services/prompt_manager_service.py
58
59
  src/iatoolkit/services/query_service.py
@@ -91,19 +92,19 @@ src/iatoolkit/templates/forgot_password.html
91
92
  src/iatoolkit/templates/header.html
92
93
  src/iatoolkit/templates/home.html
93
94
  src/iatoolkit/templates/login.html
94
- src/iatoolkit/templates/login_shell.html
95
+ src/iatoolkit/templates/onboarding_shell.html
95
96
  src/iatoolkit/templates/signup.html
96
97
  src/iatoolkit/templates/test.html
97
98
  src/iatoolkit/views/__init__.py
98
99
  src/iatoolkit/views/change_password_view.py
99
100
  src/iatoolkit/views/chat_token_request_view.py
100
101
  src/iatoolkit/views/download_file_view.py
102
+ src/iatoolkit/views/external_login_view.py
101
103
  src/iatoolkit/views/file_store_view.py
102
104
  src/iatoolkit/views/forgot_password_view.py
103
105
  src/iatoolkit/views/history_view.py
104
106
  src/iatoolkit/views/home_view.py
105
107
  src/iatoolkit/views/llmquery_view.py
106
- src/iatoolkit/views/login_external_id_view.py
107
108
  src/iatoolkit/views/login_view.py
108
109
  src/iatoolkit/views/prompt_view.py
109
110
  src/iatoolkit/views/signup_view.py
File without changes
File without changes
File without changes