iatoolkit 0.62.0__tar.gz → 0.64.7__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 (126) hide show
  1. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/PKG-INFO +1 -1
  2. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/pyproject.toml +1 -1
  3. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/common/routes.py +5 -2
  4. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/iatoolkit.py +1 -1
  5. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/branding_service.py +28 -22
  6. iatoolkit-0.64.7/src/iatoolkit/services/help_content_service.py +30 -0
  7. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/user_feedback_service.py +1 -1
  8. iatoolkit-0.64.7/src/iatoolkit/static/js/chat_feedback_button.js +82 -0
  9. iatoolkit-0.64.7/src/iatoolkit/static/js/chat_help_content.js +124 -0
  10. iatoolkit-0.64.7/src/iatoolkit/static/js/chat_history_button.js +94 -0
  11. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/js/chat_main.js +22 -5
  12. iatoolkit-0.64.7/src/iatoolkit/static/js/chat_reload_button.js +35 -0
  13. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/styles/chat_iatoolkit.css +171 -174
  14. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/styles/chat_modal.css +95 -93
  15. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/styles/landing_page.css +16 -10
  16. iatoolkit-0.64.7/src/iatoolkit/templates/_company_header.html +20 -0
  17. iatoolkit-0.64.7/src/iatoolkit/templates/_login_widget.html +40 -0
  18. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/base.html +2 -6
  19. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/change_password.html +12 -10
  20. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/chat.html +18 -9
  21. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/chat_modals.html +94 -66
  22. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/error.html +11 -13
  23. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/forgot_password.html +4 -0
  24. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/index.html +16 -14
  25. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/onboarding_shell.html +0 -1
  26. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/signup.html +3 -0
  27. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/change_password_view.py +5 -3
  28. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/forgot_password_view.py +9 -5
  29. iatoolkit-0.64.7/src/iatoolkit/views/help_content_api_view.py +50 -0
  30. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/history_api_view.py +0 -1
  31. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/home_view.py +2 -4
  32. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/login_view.py +14 -8
  33. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/signup_view.py +9 -5
  34. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/verify_user_view.py +0 -1
  35. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit.egg-info/PKG-INFO +1 -1
  36. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit.egg-info/SOURCES.txt +4 -0
  37. iatoolkit-0.62.0/src/iatoolkit/static/js/chat_feedback_button.js +0 -110
  38. iatoolkit-0.62.0/src/iatoolkit/static/js/chat_history_button.js +0 -127
  39. iatoolkit-0.62.0/src/iatoolkit/static/js/chat_reload_button.js +0 -52
  40. iatoolkit-0.62.0/src/iatoolkit/templates/_company_header.html +0 -21
  41. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/readme.md +0 -0
  42. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/requirements.txt +0 -0
  43. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/setup.cfg +0 -0
  44. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/__init__.py +0 -0
  45. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/base_company.py +0 -0
  46. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/cli_commands.py +0 -0
  47. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/common/__init__.py +0 -0
  48. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/common/exceptions.py +0 -0
  49. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/common/session_manager.py +0 -0
  50. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/common/util.py +0 -0
  51. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/company_registry.py +0 -0
  52. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/__init__.py +0 -0
  53. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/call_service.py +0 -0
  54. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  55. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  56. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  57. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  58. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  59. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  60. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  61. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/gemini_adapter.py +0 -0
  62. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/google_chat_app.py +0 -0
  63. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/llm_client.py +0 -0
  64. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/llm_proxy.py +0 -0
  65. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/llm_response.py +0 -0
  66. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/mail_app.py +0 -0
  67. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/openai_adapter.py +0 -0
  68. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  69. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/__init__.py +0 -0
  70. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/database_manager.py +0 -0
  71. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/document_repo.py +0 -0
  72. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  73. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/models.py +0 -0
  74. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/profile_repo.py +0 -0
  75. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/tasks_repo.py +0 -0
  76. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/repositories/vs_repo.py +0 -0
  77. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/__init__.py +0 -0
  78. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/auth_service.py +0 -0
  79. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/benchmark_service.py +0 -0
  80. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/dispatcher_service.py +0 -0
  81. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/document_service.py +0 -0
  82. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/excel_service.py +0 -0
  83. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/file_processor_service.py +0 -0
  84. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/history_service.py +0 -0
  85. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/jwt_service.py +0 -0
  86. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/load_documents_service.py +0 -0
  87. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/mail_service.py +0 -0
  88. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/onboarding_service.py +0 -0
  89. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/profile_service.py +0 -0
  90. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/prompt_manager_service.py +0 -0
  91. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/query_service.py +0 -0
  92. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/search_service.py +0 -0
  93. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/sql_service.py +0 -0
  94. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/tasks_service.py +0 -0
  95. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/services/user_session_context_service.py +0 -0
  96. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  97. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  98. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
  99. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
  100. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
  101. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/styles/chat_info.css +0 -0
  102. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/styles/llm_output.css +0 -0
  103. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/static/styles/onboarding.css +0 -0
  104. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
  105. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
  106. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
  107. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/about.html +0 -0
  108. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/header.html +0 -0
  109. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/login_simulation.html +0 -0
  110. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/templates/test.html +0 -0
  111. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/__init__.py +0 -0
  112. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/base_login_view.py +0 -0
  113. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/external_login_view.py +0 -0
  114. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/file_store_api_view.py +0 -0
  115. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/index_view.py +0 -0
  116. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/init_context_api_view.py +0 -0
  117. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/llmquery_api_view.py +0 -0
  118. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/login_simulation_view.py +0 -0
  119. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/logout_api_view.py +0 -0
  120. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/prompt_api_view.py +0 -0
  121. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/tasks_api_view.py +0 -0
  122. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/tasks_review_api_view.py +0 -0
  123. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  124. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  125. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/src/iatoolkit.egg-info/requires.txt +0 -0
  126. {iatoolkit-0.62.0 → iatoolkit-0.64.7}/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.62.0
3
+ Version: 0.64.7
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.62.0"
7
+ version = "0.64.7"
8
8
  requires-python = ">=3.12"
9
9
  description = "IAToolkit"
10
10
  readme = "readme.md"
@@ -5,7 +5,6 @@
5
5
 
6
6
  from flask import render_template, redirect, url_for,send_from_directory, current_app, abort
7
7
  from flask import jsonify
8
- from iatoolkit.views.history_api_view import HistoryApiView
9
8
 
10
9
 
11
10
  # this function register all the views
@@ -24,6 +23,9 @@ def register_views(injector, app):
24
23
  from iatoolkit.views.file_store_api_view import FileStoreApiView
25
24
  from iatoolkit.views.user_feedback_api_view import UserFeedbackApiView
26
25
  from iatoolkit.views.prompt_api_view import PromptApiView
26
+ from iatoolkit.views.history_api_view import HistoryApiView
27
+ from iatoolkit.views.help_content_api_view import HelpContentApiView
28
+
27
29
  from iatoolkit.views.login_view import LoginView, FinalizeContextView
28
30
  from iatoolkit.views.external_login_view import ExternalLoginView, RedeemTokenApiView
29
31
  from iatoolkit.views.logout_api_view import LogoutApiView
@@ -79,9 +81,10 @@ def register_views(injector, app):
79
81
  # open the promt directory
80
82
  app.add_url_rule('/<company_short_name>/api/prompts', view_func=PromptApiView.as_view('prompt'))
81
83
 
82
- # feedback and history
84
+ # toolbar buttons
83
85
  app.add_url_rule('/<company_short_name>/api/feedback', view_func=UserFeedbackApiView.as_view('feedback'))
84
86
  app.add_url_rule('/<company_short_name>/api/history', view_func=HistoryApiView.as_view('history'))
87
+ app.add_url_rule('/<company_short_name>/api/help-content', view_func=HelpContentApiView.as_view('help-content'))
85
88
 
86
89
  # tasks management endpoints: create task, and review answer
87
90
  app.add_url_rule('/tasks', view_func=TaskApiView.as_view('tasks'))
@@ -19,7 +19,7 @@ from werkzeug.middleware.proxy_fix import ProxyFix
19
19
  from injector import Binder, Injector, singleton
20
20
  from importlib.metadata import version as _pkg_version, PackageNotFoundError
21
21
 
22
- IATOOLKIT_VERSION = "0.62.0"
22
+ IATOOLKIT_VERSION = "0.64.7"
23
23
 
24
24
  # global variable for the unique instance of IAToolkit
25
25
  _iatoolkit_instance: Optional['IAToolkit'] = None
@@ -4,6 +4,7 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from iatoolkit.repositories.models import Company
7
+ from injector import inject
7
8
 
8
9
 
9
10
  class BrandingService:
@@ -11,6 +12,7 @@ class BrandingService:
11
12
  Servicio centralizado que gestiona la configuración de branding.
12
13
  """
13
14
 
15
+ @inject
14
16
  def __init__(self):
15
17
  """
16
18
  Define los estilos de branding por defecto para la aplicación.
@@ -19,13 +21,16 @@ class BrandingService:
19
21
  # --- Estilos del Encabezado Principal ---
20
22
  "header_background_color": "#FFFFFF",
21
23
  "header_text_color": "#6C757D",
22
- "primary_font_weight": "bold",
23
- "primary_font_size": "1rem",
24
- "secondary_font_weight": "600",
25
- "secondary_font_size": "0.875rem",
26
- "tertiary_font_weight": "normal",
27
- "tertiary_font_size": "0.75rem",
28
- "tertiary_opacity": "0.8",
24
+ "primary_font_weight": "600",
25
+ "primary_font_size": "1.2rem",
26
+ "secondary_font_weight": "400",
27
+ "secondary_font_size": "0.9rem",
28
+ "tertiary_font_weight": "300",
29
+ "tertiary_font_size": "0.8rem",
30
+ "tertiary_opacity": "0.7",
31
+
32
+ # headings
33
+ "brand_text_heading_color": "#334155", # Gris pizarra por defecto
29
34
 
30
35
  # Estilos Globales de la Marca ---
31
36
  "brand_primary_color": "#0d6efd", # Azul de Bootstrap por defecto
@@ -40,25 +45,27 @@ class BrandingService:
40
45
  "brand_danger_border": "#f5c2c7", # Borde rojo intermedio
41
46
 
42
47
  # Estilos para Alertas Informativas ---
43
- "brand_info_bg": "#cff4fc", # Fondo celeste pálido
44
- "brand_info_text": "#055160", # Texto azul oscuro
45
- "brand_info_border": "#b6effb",
48
+ "brand_info_bg": "#F0F4F8", # Un fondo de gris azulado muy pálido
49
+ "brand_info_text": "#0d6efd", # Texto en el color primario
50
+ "brand_info_border": "#D9E2EC", # Borde de gris azulado pálido
46
51
 
47
52
  # Estilos para el Asistente de Prompts ---
48
53
  "prompt_assistant_bg": "#f8f9fa",
49
54
  "prompt_assistant_border": "#dee2e6",
50
- "prompt_assistant_icon_color": "#6c757d",
51
55
  "prompt_assistant_button_bg": "#FFFFFF",
52
56
  "prompt_assistant_button_text": "#495057",
53
57
  "prompt_assistant_button_border": "#ced4da",
54
58
  "prompt_assistant_dropdown_bg": "#f8f9fa",
55
59
  "prompt_assistant_header_bg": "#e9ecef",
56
60
  "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
61
+
62
+ # this use the primary by default
63
+ "prompt_assistant_icon_color": None,
64
+ "prompt_assistant_item_hover_bg": None,
65
+ "prompt_assistant_item_hover_text": None,
59
66
 
60
67
  # Color para el botón de Enviar ---
61
- "send_button_color": "#212529" # Gris oscuro/casi negro por defecto
68
+ "send_button_color": "#212529" # Gris oscuro/casi negro por defecto
62
69
  }
63
70
 
64
71
  def get_company_branding(self, company: Company | None) -> dict:
@@ -80,10 +87,6 @@ class BrandingService:
80
87
  secondary_rgb = hex_to_rgb(final_branding_values['brand_secondary_color'])
81
88
 
82
89
  # --- CONSTRUCCIÓN DE ESTILOS Y VARIABLES CSS ---
83
- header_style = (
84
- f"background-color: {final_branding_values['header_background_color']}; "
85
- f"color: {final_branding_values['header_text_color']};"
86
- )
87
90
  primary_text_style = (
88
91
  f"font-weight: {final_branding_values['primary_font_weight']}; "
89
92
  f"font-size: {final_branding_values['primary_font_size']};"
@@ -103,6 +106,10 @@ class BrandingService:
103
106
  :root {{
104
107
  --brand-primary-color: {final_branding_values['brand_primary_color']};
105
108
  --brand-secondary-color: {final_branding_values['brand_secondary_color']};
109
+ --brand-header-bg: {final_branding_values['header_background_color']};
110
+ --brand-header-text: {final_branding_values['header_text_color']};
111
+ --brand-text-heading-color: {final_branding_values['brand_text_heading_color']};
112
+
106
113
  --brand-primary-color-rgb: {', '.join(map(str, primary_rgb))};
107
114
  --brand-secondary-color-rgb: {', '.join(map(str, secondary_rgb))};
108
115
  --brand-text-on-primary: {final_branding_values['brand_text_on_primary']};
@@ -114,11 +121,11 @@ class BrandingService:
114
121
  --brand-danger-text: {final_branding_values['brand_danger_text']};
115
122
  --brand-danger-border: {final_branding_values['brand_danger_border']};
116
123
  --brand-info-bg: {final_branding_values['brand_info_bg']};
117
- --brand-info-text: {final_branding_values['brand_info_text']};
124
+ --brand-info-text: {final_branding_values['brand_info_text'] or final_branding_values['brand_primary_color']};
118
125
  --brand-info-border: {final_branding_values['brand_info_border']};
119
126
  --brand-prompt-assistant-bg: {final_branding_values['prompt_assistant_bg']};
120
127
  --brand-prompt-assistant-border: {final_branding_values['prompt_assistant_border']};
121
- --brand-prompt-assistant-icon-color: {final_branding_values['prompt_assistant_icon_color']};
128
+ --brand-prompt-assistant-icon-color: {final_branding_values['prompt_assistant_icon_color'] or final_branding_values['brand_primary_color']};
122
129
  --brand-prompt-assistant-button-bg: {final_branding_values['prompt_assistant_button_bg']};
123
130
  --brand-prompt-assistant-button-text: {final_branding_values['prompt_assistant_button_text']};
124
131
  --brand-prompt-assistant-button-border: {final_branding_values['prompt_assistant_button_border']};
@@ -133,11 +140,10 @@ class BrandingService:
133
140
 
134
141
  return {
135
142
  "name": company.name if company else "IAToolkit",
136
- "header_style": header_style,
137
143
  "primary_text_style": primary_text_style,
138
144
  "secondary_text_style": secondary_text_style,
139
145
  "tertiary_text_style": tertiary_text_style,
140
146
  "header_text_color": final_branding_values['header_text_color'],
141
147
  "css_variables": css_variables,
142
- "send_button_color": final_branding_values['send_button_color']
148
+ "send_button_color": final_branding_values['brand_primary_color']
143
149
  }
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from iatoolkit.common.util import Utility
7
+ from iatoolkit.common.exceptions import IAToolkitException
8
+ import os
9
+ from injector import inject
10
+ import logging
11
+
12
+
13
+ class HelpContentService:
14
+ @inject
15
+ def __init__(self, util: Utility):
16
+ self.util = util
17
+
18
+ def get_content(self, company_short_name: str | None) -> dict:
19
+ filepath = f'companies/{company_short_name}/help_content.yaml'
20
+ if not os.path.exists(filepath):
21
+ return {}
22
+
23
+ # read the file
24
+ try:
25
+ help_content = self.util.load_schema_from_yaml(filepath)
26
+ return help_content
27
+ except Exception as e:
28
+ logging.exception(e)
29
+ raise IAToolkitException(IAToolkitException.ErrorType.CONFIG_ERROR,
30
+ f"Error obteniendo help de {company_short_name}: {str(e)}") from e
@@ -96,7 +96,7 @@ class UserFeedbackService:
96
96
  logging.error(f"No se pudo guardar el feedback para el usuario {user_identifier} en la empresa {company_short_name}")
97
97
  return {'error': 'No se pudo guardar el feedback'}
98
98
 
99
- return {'message': 'Feedback guardado correctamente'}
99
+ return {'success': True, 'message': 'Feedback guardado correctamente'}
100
100
 
101
101
  except Exception as e:
102
102
  logging.exception(f"Error crítico en el servicio de feedback: {e}")
@@ -0,0 +1,82 @@
1
+ $(document).ready(function () {
2
+ $('#submit-feedback').on('click', function () {
3
+ sendFeedback(this);
4
+ });
5
+
6
+ // Evento para enviar el feedback
7
+ async function sendFeedback(submitButton) {
8
+ toastr.options = {"positionClass": "toast-bottom-right", "preventDuplicates": true};
9
+ const feedbackText = $('#feedback-text').val().trim();
10
+ const activeStars = $('.star.active').length;
11
+
12
+ if (!feedbackText) {
13
+ toastr.error('Por favor, escribe tu comentario antes de enviar.');
14
+ return;
15
+ }
16
+
17
+ if (activeStars === 0) {
18
+ toastr.error('Por favor, califica al asistente con las estrellas.');
19
+ return;
20
+ }
21
+
22
+ submitButton.disabled = true;
23
+
24
+ // call the IAToolkit API to send feedback
25
+ const data = {
26
+ "user_identifier": window.user_identifier,
27
+ "message": feedbackText,
28
+ "rating": activeStars,
29
+ };
30
+
31
+ const responseData = await callToolkit('/api/feedback', data, "POST");
32
+ if (responseData)
33
+ toastr.success('¡Gracias por tu comentario!', 'Feedback Enviado');
34
+ else
35
+ toastr.error('No se pudo enviar el feedback, por favor intente nuevamente.');
36
+
37
+ submitButton.disabled = false;
38
+ $('#feedbackModal').modal('hide');
39
+ }
40
+
41
+ // Evento para abrir el modal de feedback
42
+ $('#send-feedback-button').on('click', function () {
43
+ $('#submit-feedback').prop('disabled', false);
44
+ $('#submit-feedback').html('<i class="bi bi-send me-1 icon-spaced"></i>Enviar');
45
+ $('.star').removeClass('active hover-active'); // Resetea estrellas
46
+ $('#feedback-text').val(''); // Limpia texto
47
+ $('.modal-body .alert').remove(); // Quita alertas previas
48
+ $('#feedbackModal').modal('show');
49
+ });
50
+
51
+ // Evento que se dispara DESPUÉS de que el modal se ha ocultado
52
+ $('#feedbackModal').on('hidden.bs.modal', function () {
53
+ $('#feedback-text').val('');
54
+ $('.modal-body .alert').remove();
55
+ $('.star').removeClass('active');
56
+ });
57
+
58
+ // Función para el sistema de estrellas
59
+ window.gfg = function (rating) {
60
+ $('.star').removeClass('active');
61
+ $('.star').each(function (index) {
62
+ if (index < rating) {
63
+ $(this).addClass('active');
64
+ }
65
+ });
66
+ };
67
+
68
+ $('.star').hover(
69
+ function () {
70
+ const rating = $(this).data('rating');
71
+ $('.star').removeClass('hover-active');
72
+ $('.star').each(function (index) {
73
+ if ($(this).data('rating') <= rating) {
74
+ $(this).addClass('hover-active');
75
+ }
76
+ });
77
+ },
78
+ function () {
79
+ $('.star').removeClass('hover-active');
80
+ });
81
+
82
+ });
@@ -0,0 +1,124 @@
1
+ $(document).ready(function () {
2
+
3
+ let helpContent = null; // Variable para cachear el contenido de ayuda
4
+
5
+ // Evento de clic en el botón de ayuda
6
+ $('#open-help-button').on('click', async function () {
7
+ const helpModal = new bootstrap.Modal(document.getElementById('helpModal'));
8
+ const accordionContainer = $('#help-accordion-container');
9
+ const spinner = $('#help-spinner');
10
+
11
+ // Si el contenido no se ha cargado, hacer la llamada a la API
12
+ if (helpContent) {
13
+ // Si el contenido ya está cacheado, solo muestra el modal
14
+ helpModal.show();
15
+ return;
16
+ }
17
+
18
+ spinner.show();
19
+ accordionContainer.hide();
20
+ helpModal.show();
21
+
22
+ try {
23
+ const helpContent = await callToolkit('/api/help-content', {}, "POST");
24
+
25
+ if (!helpContent) {
26
+ toastr.error('No se pudo cargar la guía de uso. Por favor, intente más tarde.');
27
+ spinner.hide();
28
+ helpModal.hide();
29
+ return;
30
+ }
31
+
32
+ // Construir el HTML del acordeón y mostrarlo
33
+ buildHelpAccordion(helpContent);
34
+ spinner.hide();
35
+ accordionContainer.show();
36
+
37
+ } catch (error) {
38
+ console.error("Error al cargar el contenido de ayuda:", error);
39
+ toastr.error('Ocurrió un error de red al cargar la guía.');
40
+ spinner.hide();
41
+ helpModal.hide();
42
+ }
43
+ });
44
+
45
+ /**
46
+ * Construye dinámicamente el HTML para el acordeón de ayuda a partir de los datos.
47
+ * @param {object} data El objeto JSON con el contenido de ayuda.
48
+ */
49
+ function buildHelpAccordion(data) {
50
+ const container = $('#help-accordion-container');
51
+ container.empty(); // Limpiar cualquier contenido previo
52
+
53
+ let accordionHtml = '';
54
+
55
+ if (data.data_sources) {
56
+ let contentHtml = '<dl>';
57
+ data.data_sources.forEach(p => {
58
+ contentHtml += `<dt>${p.source}</dt><dd>${p.description}</dd>`;
59
+ });
60
+ contentHtml += `</dl>`;
61
+ accordionHtml += createAccordionItem('sources', 'Datos disponibles', contentHtml, true);
62
+ }
63
+
64
+ if (data.example_questions) {
65
+ let contentHtml = '';
66
+ data.example_questions.forEach(cat => {
67
+ contentHtml += `<h6 class="fw-bold">${cat.category}</h6><ul>`;
68
+ cat.questions.forEach(q => contentHtml += `<li>${q}</li>`);
69
+ contentHtml += `</ul>`;
70
+ });
71
+ accordionHtml += createAccordionItem('examples', 'Preguntas de Ejemplo', contentHtml);
72
+ }
73
+
74
+ if (data.best_practices) {
75
+ let contentHtml = '<dl>';
76
+ data.best_practices.forEach(p => {
77
+ contentHtml += `<dt>${p.title}</dt><dd>${p.description}`;
78
+ if (p.example) {
79
+ contentHtml += `<br><small class="text-muted"><em>Ej: "${p.example}"</em></small>`;
80
+ }
81
+ contentHtml += `</dd>`;
82
+ });
83
+ contentHtml += `</dl>`;
84
+ accordionHtml += createAccordionItem('practices', 'Mejores Prácticas', contentHtml);
85
+ }
86
+
87
+ if (data.capabilities) {
88
+ let contentHtml = `<div class="row">`;
89
+ contentHtml += `<div class="col-md-6"><h6 class="fw-bold">Puede hacer:</h6><ul>${data.capabilities.can_do.map(item => `<li>${item}</li>`).join('')}</ul></div>`;
90
+ contentHtml += `<div class="col-md-6"><h6 class="fw-bold">No puede hacer:</h6><ul>${data.capabilities.cannot_do.map(item => `<li>${item}</li>`).join('')}</ul></div>`;
91
+ contentHtml += `</div>`;
92
+ accordionHtml += createAccordionItem('capabilities', 'Capacidades y Límites', contentHtml);
93
+ }
94
+
95
+ container.html(accordionHtml);
96
+ }
97
+
98
+ /**
99
+ * Helper para crear un item del acordeón de Bootstrap.
100
+ * @param {string} id El ID base para los elementos.
101
+ * @param {string} title El título que se muestra en el botón del acordeón.
102
+ * @param {string} contentHtml El HTML que va dentro del cuerpo colapsable.
103
+ * @param {boolean} isOpen Si el item debe estar abierto por defecto.
104
+ * @returns {string} El string HTML del item del acordeón.
105
+ */
106
+ function createAccordionItem(id, title, contentHtml, isOpen = false) {
107
+ const showClass = isOpen ? 'show' : '';
108
+ const collapsedClass = isOpen ? '' : 'collapsed';
109
+
110
+ return `
111
+ <div class="accordion-item">
112
+ <h2 class="accordion-header" id="heading-${id}">
113
+ <button class="accordion-button ${collapsedClass}" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-${id}" aria-expanded="${isOpen}" aria-controls="collapse-${id}">
114
+ ${title}
115
+ </button>
116
+ </h2>
117
+ <div id="collapse-${id}" class="accordion-collapse collapse ${showClass}" aria-labelledby="heading-${id}" data-bs-parent="#help-accordion-container">
118
+ <div class="accordion-body">
119
+ ${contentHtml}
120
+ </div>
121
+ </div>
122
+ </div>`;
123
+ }
124
+ });
@@ -0,0 +1,94 @@
1
+ $(document).ready(function () {
2
+ // Evento para abrir el modal de historial
3
+ $('#history-button').on('click', function() {
4
+ loadHistory();
5
+ });
6
+
7
+
8
+ // Función para cargar el historial
9
+ async function loadHistory() {
10
+ const historyLoading = $('#history-loading');
11
+
12
+ historyLoading.show();
13
+
14
+ // cal the toolkit, handle the response and errors
15
+ const data = await callToolkit("/api/history", {}, "POST");
16
+
17
+ if (data && data.history) {
18
+ $('#historyModal').modal('show');
19
+ displayAllHistory(data.history);
20
+ $('#history-content').show();
21
+ }
22
+ historyLoading.hide();
23
+ }
24
+
25
+ // Función para mostrar todo el historial
26
+ function displayAllHistory(historyData) {
27
+ const historyTableBody = $('#history-table-body');
28
+
29
+ historyTableBody.empty();
30
+
31
+ // Filtrar solo consultas que son strings simples
32
+ const filteredHistory = historyData.filter(item => {
33
+ try {
34
+ JSON.parse(item.query);
35
+ return false;
36
+ } catch (e) {
37
+ return true;
38
+ }
39
+ });
40
+
41
+ // Poblar la tabla
42
+ filteredHistory.forEach((item, index) => {
43
+ const icon = $('<i>').addClass('bi bi-pencil-fill');
44
+
45
+ const link = $('<a>')
46
+ .attr('href', 'javascript:void(0);')
47
+ .addClass('edit-pencil')
48
+ .attr('title', 'Copiar consulta al chat')
49
+ .data('query', item.query)
50
+ .append(icon);
51
+
52
+ const row = $('<tr>').append(
53
+ $('<td>').addClass('text-nowrap').text(formatDate(item.created_at)),
54
+ $('<td>').text(item.query),
55
+ $('<td>').append(link),
56
+ );
57
+
58
+ historyTableBody.append(row);
59
+ });
60
+ }
61
+
62
+ function formatDate(dateString) {
63
+ const date = new Date(dateString);
64
+
65
+ const padTo2Digits = (num) => num.toString().padStart(2, '0');
66
+
67
+ const day = padTo2Digits(date.getDate());
68
+ const month = padTo2Digits(date.getMonth() + 1);
69
+ const year = date.getFullYear();
70
+ const hours = padTo2Digits(date.getHours());
71
+ const minutes = padTo2Digits(date.getMinutes());
72
+
73
+ return `${day}-${month} ${hours}:${minutes}`;
74
+ }
75
+
76
+ // event handler for the edit pencil icon
77
+ $('#history-table-body').on('click', '.edit-pencil', function() {
78
+ const queryText = $(this).data('query');
79
+
80
+ // copy the text to the chat input box
81
+ if (queryText) {
82
+ $('#question').val(queryText);
83
+ autoResizeTextarea($('#question')[0]);
84
+ $('#send-button').removeClass('disabled');
85
+
86
+ // Cerrar el modal
87
+ $('#historyModal').modal('hide');
88
+
89
+ // Hacer focus en el textarea
90
+ if (window.innerWidth > 768)
91
+ $('#question').focus();
92
+ }
93
+ });
94
+ });
@@ -11,6 +11,22 @@ $(document).ready(function () {
11
11
  callToolkit(url, {'token': window.redeemToken}, "POST").catch(() => {});
12
12
  }
13
13
 
14
+ const layoutContainer = document.querySelector('.chat-layout-container');
15
+ const promptAssistantCollapse = document.getElementById('prompt-assistant-collapse');
16
+
17
+ if (layoutContainer && promptAssistantCollapse) {
18
+ promptAssistantCollapse.addEventListener('show.bs.collapse', function () {
19
+ layoutContainer.classList.add('prompt-assistant-open');
20
+ setTimeout(() => {
21
+ window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
22
+ }, 300);
23
+ });
24
+
25
+ promptAssistantCollapse.addEventListener('hide.bs.collapse', function () {
26
+ layoutContainer.classList.remove('prompt-assistant-open');
27
+ });
28
+ }
29
+
14
30
  // --- chat main event hadlers ---
15
31
  $('#send-button').on('click', handleChatMessage);
16
32
  $('#stop-button').on('click', abortCurrentRequest);
@@ -183,7 +199,6 @@ const toggleSendStopButtons = function (showStop) {
183
199
  $('#stop-button-container').toggle(showStop);
184
200
  };
185
201
 
186
-
187
202
  /**
188
203
  * Generic function to make API calls to the backend.
189
204
  * @param {string} apiPath - The API endpoint path.
@@ -273,11 +288,13 @@ const displayUserMessage = function(message, isEditable, originalQuestion) {
273
288
  userMessage.append(messageText);
274
289
 
275
290
  if (isEditable) {
276
- const editIcon = $('<i>').addClass('p-2 bi bi-pencil-fill edit-icon').attr('title', 'Edit query').on('click', function () {
277
- $('#question').val(originalQuestion).focus();
291
+ const editIcon = $('<i>').addClass('p-2 bi bi-pencil-fill edit-icon edit-pencil').attr('title', 'Edit query').on('click', function () {
292
+ $('#question').val(originalQuestion)
278
293
  autoResizeTextarea($('#question')[0]);
279
-
280
294
  $('#send-button').removeClass('disabled');
295
+
296
+ if (window.innerWidth > 768)
297
+ $('#question').focus();
281
298
  });
282
299
  userMessage.append(editIcon);
283
300
  }
@@ -312,7 +329,7 @@ const showSpinner = function () {
312
329
  const accessibilityClass = (typeof bootstrap !== 'undefined') ? 'visually-hidden' : 'sr-only';
313
330
  const spinner = $(`
314
331
  <div id="spinner" style="display: flex; align-items: center; justify-content: start; margin: 10px 0; padding: 10px;">
315
- <div class="spinner-border text-primary" role="status" style="width: 1.5rem; height: 1.5rem; margin-right: 15px;">
332
+ <div class="spinner-border" role="status" style="width: 1.5rem; height: 1.5rem; margin-right: 15px;">
316
333
  <span class="${accessibilityClass}">Loading...</span>
317
334
  </div>
318
335
  <span style="font-weight: bold; font-size: 15px;">Cargando...</span>
@@ -0,0 +1,35 @@
1
+ $(document).ready(function () {
2
+ $('#force-reload-button').on('click', function() {
3
+ reloadButton(this);
4
+ });
5
+
6
+ async function reloadButton(button) {
7
+ const originalIconClass = 'bi bi-arrow-clockwise';
8
+ const spinnerIconClass = 'spinner-border spinner-border-sm';
9
+
10
+ // Configuración de Toastr para que aparezca abajo a la derecha
11
+ toastr.options = {"positionClass": "toast-bottom-right", "preventDuplicates": true};
12
+
13
+ // 1. Deshabilitar y mostrar spinner
14
+ button.disabled = true;
15
+ const icon = button.querySelector('i');
16
+ icon.className = spinnerIconClass;
17
+ toastr.info('Iniciando recarga de contexto en segundo plano...');
18
+
19
+ // 2. prepare the api parameters
20
+ const apiPath = '/api/init-context';
21
+ const payload = {'user_identifier': window.user_identifier};
22
+
23
+ // 3. make the call to callToolkit
24
+ const data = await callToolkit(apiPath, payload, 'POST');
25
+ if (data) {
26
+ if (data.status === 'OK')
27
+ toastr.success(data.message || 'Contexto recargado.');
28
+ else
29
+ toastr.error(data.error_message || 'Ocurrió un error desconocido durante la recarga.');
30
+ }
31
+
32
+ button.disabled = false;
33
+ icon.className = originalIconClass;
34
+ }
35
+ });