iatoolkit 0.7.10__py3-none-any.whl → 0.7.11__py3-none-any.whl

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/__init__.py +18 -14
  2. iatoolkit/base_company.py +5 -5
  3. iatoolkit/cli_commands.py +5 -3
  4. {common → iatoolkit/common}/auth.py +3 -3
  5. {common → iatoolkit/common}/routes.py +19 -19
  6. {common → iatoolkit/common}/util.py +2 -2
  7. iatoolkit/iatoolkit.py +37 -38
  8. {infra → iatoolkit/infra}/call_service.py +1 -1
  9. {infra → iatoolkit/infra}/connectors/file_connector_factory.py +5 -5
  10. {infra → iatoolkit/infra}/connectors/google_cloud_storage_connector.py +1 -1
  11. {infra → iatoolkit/infra}/connectors/google_drive_connector.py +1 -1
  12. {infra → iatoolkit/infra}/connectors/local_file_connector.py +2 -2
  13. {infra → iatoolkit/infra}/connectors/s3_connector.py +1 -1
  14. {infra → iatoolkit/infra}/gemini_adapter.py +2 -2
  15. {infra → iatoolkit/infra}/google_chat_app.py +1 -1
  16. {infra → iatoolkit/infra}/llm_client.py +7 -7
  17. {infra → iatoolkit/infra}/llm_proxy.py +6 -6
  18. {infra → iatoolkit/infra}/mail_app.py +1 -1
  19. {infra → iatoolkit/infra}/openai_adapter.py +2 -2
  20. {repositories → iatoolkit/repositories}/database_manager.py +1 -1
  21. {repositories → iatoolkit/repositories}/document_repo.py +3 -3
  22. {repositories → iatoolkit/repositories}/llm_query_repo.py +2 -2
  23. {repositories → iatoolkit/repositories}/profile_repo.py +2 -2
  24. {repositories → iatoolkit/repositories}/tasks_repo.py +2 -2
  25. {repositories → iatoolkit/repositories}/vs_repo.py +3 -3
  26. {services → iatoolkit/services}/benchmark_service.py +3 -3
  27. {services → iatoolkit/services}/dispatcher_service.py +9 -8
  28. {services → iatoolkit/services}/document_service.py +1 -1
  29. {services → iatoolkit/services}/excel_service.py +2 -2
  30. {services → iatoolkit/services}/file_processor_service.py +2 -2
  31. {services → iatoolkit/services}/history_service.py +4 -3
  32. {services → iatoolkit/services}/load_documents_service.py +11 -10
  33. {services → iatoolkit/services}/mail_service.py +2 -2
  34. {services → iatoolkit/services}/profile_service.py +6 -6
  35. {services → iatoolkit/services}/prompt_manager_service.py +5 -4
  36. {services → iatoolkit/services}/query_service.py +12 -11
  37. {services → iatoolkit/services}/search_service.py +2 -2
  38. {services → iatoolkit/services}/sql_service.py +4 -3
  39. {services → iatoolkit/services}/tasks_service.py +6 -6
  40. {services → iatoolkit/services}/user_feedback_service.py +3 -3
  41. {services → iatoolkit/services}/user_session_context_service.py +1 -1
  42. iatoolkit/static/images/arrow_up.png +0 -0
  43. iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
  44. iatoolkit/static/images/logo_clinica.png +0 -0
  45. iatoolkit/static/images/logo_iatoolkit.png +0 -0
  46. iatoolkit/static/images/logo_maxxa.png +0 -0
  47. iatoolkit/static/images/logo_notaria.png +0 -0
  48. iatoolkit/static/images/logo_tarjeta.png +0 -0
  49. iatoolkit/static/images/logo_umayor.png +0 -0
  50. iatoolkit/static/images/upload.png +0 -0
  51. iatoolkit/static/js/chat_feedback.js +115 -0
  52. iatoolkit/static/js/chat_filepond.js +85 -0
  53. iatoolkit/static/js/chat_history.js +117 -0
  54. iatoolkit/static/js/chat_main.js +436 -0
  55. iatoolkit/static/styles/chat_iatoolkit.css +701 -0
  56. iatoolkit/static/styles/chat_info.css +53 -0
  57. iatoolkit/static/styles/chat_modal.css +136 -0
  58. iatoolkit/static/styles/llm_output.css +115 -0
  59. iatoolkit/static/temp/024f44a9-cc7e-4bde-9a3c-11903a8f5d3d.xlsx +0 -0
  60. iatoolkit/static/temp/0b97768e-79e8-43ec-b17e-ba3137f94e93.xlsx +0 -0
  61. iatoolkit/static/temp/202883ee-763e-4b40-9bb6-bfacfc5e65fe.xlsx +0 -0
  62. iatoolkit/static/temp/28287491-08b7-4863-a2a3-49fcb64a0906.xlsx +0 -0
  63. iatoolkit/static/temp/36780cac-7a46-4db4-ac98-7338a51aaf52.xlsx +0 -0
  64. iatoolkit/static/temp/5c1b66f6-d58f-4684-8a7a-df3bb1a35eaa.xlsx +0 -0
  65. iatoolkit/static/temp/5d5a3500-ec57-4e07-a554-8799a906d1ab.xlsx +0 -0
  66. iatoolkit/static/temp/65887e40-cf64-49aa-8d1f-651cb0f8cdf0.xlsx +0 -0
  67. iatoolkit/static/temp/6fa64b13-e8e5-40ad-8257-00fd1682dad8.xlsx +0 -0
  68. iatoolkit/static/temp/7ab7071f-ad9b-49e6-8e63-f08410625ce7.xlsx +0 -0
  69. iatoolkit/static/temp/824346d9-d54d-40c6-b5c2-9e1d84d0ae90.xlsx +0 -0
  70. iatoolkit/static/temp/9ca80c3d-d196-4dfc-8179-582584fae04c.xlsx +0 -0
  71. iatoolkit/static/temp/a34cb8a6-85fb-4ea8-aabe-889967cd83b5.xlsx +0 -0
  72. iatoolkit/static/temp/a7fc9c13-c509-4499-b4be-23bfa57cac31.xlsx +0 -0
  73. iatoolkit/static/temp/b83084f5-fe54-4580-885e-412b4388cbda.xlsx +0 -0
  74. iatoolkit/static/temp/c17c6864-34e1-448f-b0e9-380354256ea9.xlsx +0 -0
  75. iatoolkit/static/temp/customer_clusters.parquet +0 -0
  76. iatoolkit/static/temp/customer_clusters.xlsx +0 -0
  77. iatoolkit/static/temp/d1af98b8-18a9-4b94-b9bc-607d19a87d0d.xlsx +0 -0
  78. iatoolkit/templates/about.html +13 -0
  79. iatoolkit/templates/base.html +45 -0
  80. iatoolkit/templates/change_password.html +45 -0
  81. iatoolkit/templates/chat.html +180 -0
  82. iatoolkit/templates/chat_modals.html +115 -0
  83. iatoolkit/templates/error.html +15 -0
  84. iatoolkit/templates/forgot_password.html +33 -0
  85. iatoolkit/templates/header.html +31 -0
  86. iatoolkit/templates/home.html +201 -0
  87. iatoolkit/templates/login.html +43 -0
  88. iatoolkit/templates/signup.html +78 -0
  89. iatoolkit/templates/test.html +9 -0
  90. {views → iatoolkit/views}/change_password_view.py +1 -1
  91. {views → iatoolkit/views}/chat_token_request_view.py +2 -2
  92. {views → iatoolkit/views}/chat_view.py +3 -3
  93. {views → iatoolkit/views}/download_file_view.py +3 -3
  94. {views → iatoolkit/views}/external_chat_login_view.py +5 -5
  95. {views → iatoolkit/views}/external_login_view.py +2 -2
  96. {views → iatoolkit/views}/file_store_view.py +2 -2
  97. {views → iatoolkit/views}/forgot_password_view.py +1 -1
  98. {views → iatoolkit/views}/history_view.py +2 -2
  99. {views → iatoolkit/views}/home_view.py +1 -1
  100. {views → iatoolkit/views}/llmquery_view.py +2 -2
  101. {views → iatoolkit/views}/login_view.py +1 -1
  102. {views → iatoolkit/views}/prompt_view.py +2 -2
  103. {views → iatoolkit/views}/signup_view.py +1 -1
  104. {views → iatoolkit/views}/tasks_review_view.py +2 -2
  105. {views → iatoolkit/views}/tasks_view.py +2 -2
  106. {views → iatoolkit/views}/user_feedback_view.py +2 -2
  107. {views → iatoolkit/views}/verify_user_view.py +1 -1
  108. {iatoolkit-0.7.10.dist-info → iatoolkit-0.7.11.dist-info}/METADATA +1 -1
  109. iatoolkit-0.7.11.dist-info/RECORD +128 -0
  110. iatoolkit-0.7.11.dist-info/top_level.txt +1 -0
  111. iatoolkit-0.7.10.dist-info/RECORD +0 -80
  112. iatoolkit-0.7.10.dist-info/top_level.txt +0 -6
  113. {common → iatoolkit/common}/__init__.py +0 -0
  114. {common → iatoolkit/common}/exceptions.py +0 -0
  115. {common → iatoolkit/common}/session_manager.py +0 -0
  116. {infra → iatoolkit/infra}/__init__.py +0 -0
  117. {infra → iatoolkit/infra}/connectors/__init__.py +0 -0
  118. {infra → iatoolkit/infra}/connectors/file_connector.py +0 -0
  119. {infra → iatoolkit/infra}/llm_response.py +0 -0
  120. {infra → iatoolkit/infra}/redis_session_manager.py +0 -0
  121. {repositories → iatoolkit/repositories}/__init__.py +0 -0
  122. {repositories → iatoolkit/repositories}/models.py +0 -0
  123. {services → iatoolkit/services}/__init__.py +0 -0
  124. {services → iatoolkit/services}/jwt_service.py +0 -0
  125. {views → iatoolkit/views}/__init__.py +0 -0
  126. {iatoolkit-0.7.10.dist-info → iatoolkit-0.7.11.dist-info}/WHEEL +0 -0
@@ -3,11 +3,11 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from infra.connectors.file_connector import FileConnector
6
+ from iatoolkit.infra.connectors.file_connector import FileConnector
7
7
  import logging
8
8
  import os
9
9
  from typing import Optional, Callable, Dict
10
- from repositories.models import Company
10
+ from iatoolkit.repositories.models import Company
11
11
 
12
12
 
13
13
  class FileProcessorConfig:
@@ -4,9 +4,10 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from injector import inject
7
- from repositories.llm_query_repo import LLMQueryRepo
8
- from repositories.profile_repo import ProfileRepo
9
- from common.util import Utility
7
+ from iatoolkit.repositories.llm_query_repo import LLMQueryRepo
8
+
9
+ from iatoolkit.repositories.profile_repo import ProfileRepo
10
+ from iatoolkit.common.util import Utility
10
11
 
11
12
 
12
13
  class HistoryService:
@@ -3,17 +3,18 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from repositories.vs_repo import VSRepo
7
- from repositories.document_repo import DocumentRepo
8
- from repositories.profile_repo import ProfileRepo
9
- from repositories.llm_query_repo import LLMQueryRepo
10
- from repositories.models import Document, VSDoc, Company
11
- from services.document_service import DocumentService
6
+ from iatoolkit.repositories.vs_repo import VSRepo
7
+ from iatoolkit.repositories.document_repo import DocumentRepo
8
+ from iatoolkit.repositories.profile_repo import ProfileRepo
9
+ from iatoolkit.repositories.llm_query_repo import LLMQueryRepo
10
+
11
+ from iatoolkit.repositories.models import Document, VSDoc, Company
12
+ from iatoolkit.services.document_service import DocumentService
12
13
  from langchain.text_splitter import RecursiveCharacterTextSplitter
13
- from infra.connectors.file_connector_factory import FileConnectorFactory
14
- from services.file_processor_service import FileProcessorConfig, FileProcessor
15
- from services.dispatcher_service import Dispatcher
16
- from common.exceptions import IAToolkitException
14
+ from iatoolkit.infra.connectors.file_connector_factory import FileConnectorFactory
15
+ from iatoolkit.services.file_processor_service import FileProcessorConfig, FileProcessor
16
+ from iatoolkit.services.dispatcher_service import Dispatcher
17
+ from iatoolkit.common.exceptions import IAToolkitException
17
18
  import logging
18
19
  import base64
19
20
  from injector import inject
@@ -3,10 +3,10 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from infra.mail_app import MailApp
6
+ from iatoolkit.infra.mail_app import MailApp
7
7
  from injector import inject
8
8
  from pathlib import Path
9
- from common.exceptions import IAToolkitException
9
+ from iatoolkit.common.exceptions import IAToolkitException
10
10
  import base64
11
11
 
12
12
  TEMP_DIR = Path("static/temp")
@@ -4,20 +4,20 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from injector import inject
7
- from repositories.profile_repo import ProfileRepo
8
- from repositories.models import User, Company, ApiKey
7
+ from iatoolkit.repositories.profile_repo import ProfileRepo
8
+ from iatoolkit.repositories.models import User, Company, ApiKey
9
9
  from flask_bcrypt import check_password_hash
10
- from common.session_manager import SessionManager
10
+ from iatoolkit.common.session_manager import SessionManager
11
11
  from flask_bcrypt import Bcrypt
12
- from infra.mail_app import MailApp
12
+ from iatoolkit.infra.mail_app import MailApp
13
13
  import random
14
14
  import logging
15
15
  import re
16
16
  import secrets
17
17
  import string
18
18
  from datetime import datetime, timezone
19
- from services.user_session_context_service import UserSessionContextService
20
- from services.query_service import QueryService
19
+ from iatoolkit.services.user_session_context_service import UserSessionContextService
20
+ from iatoolkit.services.query_service import QueryService
21
21
 
22
22
 
23
23
  class ProfileService:
@@ -4,13 +4,14 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from injector import inject
7
- from repositories.llm_query_repo import LLMQueryRepo
7
+ from iatoolkit.repositories.llm_query_repo import LLMQueryRepo
8
+
8
9
  import logging
9
- from repositories.profile_repo import ProfileRepo
10
+ from iatoolkit.repositories.profile_repo import ProfileRepo
10
11
  from collections import defaultdict
11
- from repositories.models import Prompt, PromptCategory, Company
12
+ from iatoolkit.repositories.models import Prompt, PromptCategory, Company
12
13
  import os
13
- from common.exceptions import IAToolkitException
14
+ from iatoolkit.common.exceptions import IAToolkitException
14
15
  import importlib.resources
15
16
 
16
17
 
@@ -3,17 +3,18 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from infra.llm_client import llmClient
7
- from repositories.document_repo import DocumentRepo
8
- from repositories.profile_repo import ProfileRepo
9
- from services.document_service import DocumentService
10
- from repositories.llm_query_repo import LLMQueryRepo
11
- from repositories.models import Task
12
- from services.dispatcher_service import Dispatcher
13
- from services.prompt_manager_service import PromptService
14
- from services.user_session_context_service import UserSessionContextService
15
- from common.util import Utility
16
- from common.exceptions import IAToolkitException
6
+ from iatoolkit.infra.llm_client import llmClient
7
+ from iatoolkit.repositories.document_repo import DocumentRepo
8
+ from iatoolkit.repositories.profile_repo import ProfileRepo
9
+ from iatoolkit.services.document_service import DocumentService
10
+ from iatoolkit.repositories.llm_query_repo import LLMQueryRepo
11
+
12
+ from iatoolkit.repositories.models import Task
13
+ from iatoolkit.services.dispatcher_service import Dispatcher
14
+ from iatoolkit.services.prompt_manager_service import PromptService
15
+ from iatoolkit.services.user_session_context_service import UserSessionContextService
16
+ from iatoolkit.common.util import Utility
17
+ from iatoolkit.common.exceptions import IAToolkitException
17
18
  from injector import inject
18
19
  import base64
19
20
  import logging
@@ -3,8 +3,8 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from repositories.vs_repo import VSRepo
7
- from repositories.document_repo import DocumentRepo
6
+ from iatoolkit.repositories.vs_repo import VSRepo
7
+ from iatoolkit.repositories.document_repo import DocumentRepo
8
8
  from injector import inject
9
9
 
10
10
 
@@ -3,12 +3,13 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from repositories.database_manager import DatabaseManager
7
- from common.util import Utility
6
+ from iatoolkit.repositories.database_manager import DatabaseManager
7
+
8
+ from iatoolkit.common.util import Utility
8
9
  from sqlalchemy import text
9
10
  from injector import inject
10
11
  import json
11
- from common.exceptions import IAToolkitException
12
+ from iatoolkit.common.exceptions import IAToolkitException
12
13
 
13
14
 
14
15
  class SqlService:
@@ -4,12 +4,12 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  from injector import inject
7
- from repositories.models import Task, TaskStatus
8
- from services.query_service import QueryService
9
- from repositories.tasks_repo import TaskRepo
10
- from repositories.profile_repo import ProfileRepo
11
- from infra.call_service import CallServiceClient
12
- from common.exceptions import IAToolkitException
7
+ from iatoolkit.repositories.models import Task, TaskStatus
8
+ from iatoolkit.services.query_service import QueryService
9
+ from iatoolkit.repositories.tasks_repo import TaskRepo
10
+ from iatoolkit.repositories.profile_repo import ProfileRepo
11
+ from iatoolkit.infra.call_service import CallServiceClient
12
+ from iatoolkit.common.exceptions import IAToolkitException
13
13
  from datetime import datetime
14
14
  from werkzeug.utils import secure_filename
15
15
 
@@ -3,10 +3,10 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from repositories.models import UserFeedback
6
+ from iatoolkit.repositories.models import UserFeedback
7
7
  from injector import inject
8
- from repositories.profile_repo import ProfileRepo
9
- from infra.google_chat_app import GoogleChatApp
8
+ from iatoolkit.repositories.profile_repo import ProfileRepo
9
+ from iatoolkit.infra.google_chat_app import GoogleChatApp
10
10
  import logging
11
11
 
12
12
 
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- from infra.redis_session_manager import RedisSessionManager
6
+ from iatoolkit.infra.redis_session_manager import RedisSessionManager
7
7
  from typing import List, Dict, Optional
8
8
  import json
9
9
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,115 @@
1
+ $(document).ready(function () {
2
+
3
+ // Evento para enviar el feedback
4
+ $('#submit-feedback').on('click', async function() {
5
+ const feedbackText = $('#feedback-text').val().trim();
6
+ const submitButton = $(this);
7
+
8
+ // --- LÓGICA DE COMPATIBILIDAD BS3 / BS5 ---
9
+ // Detecta si Bootstrap 5 está presente.
10
+ const isBootstrap5 = (typeof bootstrap !== 'undefined');
11
+
12
+ // Define el HTML del botón de cierre según la versión.
13
+ const closeButtonHtml = isBootstrap5 ?
14
+ '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' : // Versión BS5
15
+ '<button type="button" class="close" data-dismiss="alert"><span>&times;</span></button>'; // Versión BS3/BS4
16
+ // --- FIN DE LA LÓGICA DE COMPATIBILIDAD ---
17
+
18
+ if (!feedbackText) {
19
+ const alertHtml = `
20
+ <div class="alert alert-warning alert-dismissible fade show" role="alert">
21
+ <strong>¡Atención!</strong> Por favor, escribe tu comentario antes de enviar.
22
+ ${closeButtonHtml}
23
+ </div>`;
24
+ $('.modal-body .alert').remove();
25
+ $('.modal-body').prepend(alertHtml);
26
+ return;
27
+ }
28
+
29
+ const activeStars = $('.star.active').length;
30
+ if (activeStars === 0) {
31
+ const alertHtml = `
32
+ <div class="alert alert-warning alert-dismissible fade show" role="alert">
33
+ <strong>¡Atención!</strong> Por favor, califica al asistente con las estrellas.
34
+ ${closeButtonHtml}
35
+ </div>`;
36
+ $('.modal-body .alert').remove();
37
+ $('.modal-body').prepend(alertHtml);
38
+ return;
39
+ }
40
+
41
+ submitButton.prop('disabled', true);
42
+ submitButton.html('<i class="bi bi-send me-1 icon-spaced"></i>Enviando...');
43
+
44
+ const response = await sendFeedback(feedbackText);
45
+
46
+ $('#feedbackModal').modal('hide');
47
+
48
+ if (response) {
49
+ Swal.fire({ icon: 'success', title: 'Feedback enviado', text: 'Gracias por tu comentario.' });
50
+ } else {
51
+ Swal.fire({ icon: 'error', title: 'Error', text: 'No se pudo enviar el feedback, intente nuevamente.' });
52
+ }
53
+ });
54
+
55
+ // Evento para abrir el modal de feedback
56
+ $('#send-feedback-button').on('click', function() {
57
+ $('#submit-feedback').prop('disabled', false);
58
+ $('#submit-feedback').html('<i class="bi bi-send me-1 icon-spaced"></i>Enviar');
59
+ $('.star').removeClass('active hover-active'); // Resetea estrellas
60
+ $('#feedback-text').val(''); // Limpia texto
61
+ $('.modal-body .alert').remove(); // Quita alertas previas
62
+ $('#feedbackModal').modal('show');
63
+ });
64
+
65
+ // Evento que se dispara DESPUÉS de que el modal se ha ocultado
66
+ $('#feedbackModal').on('hidden.bs.modal', function () {
67
+ $('#feedback-text').val('');
68
+ $('.modal-body .alert').remove();
69
+ $('.star').removeClass('active');
70
+ });
71
+
72
+ // Función para el sistema de estrellas
73
+ window.gfg = function(rating) {
74
+ $('.star').removeClass('active');
75
+ $('.star').each(function(index) {
76
+ if (index < rating) {
77
+ $(this).addClass('active');
78
+ }
79
+ });
80
+ };
81
+
82
+ $('.star').hover(
83
+ function() {
84
+ const rating = $(this).data('rating');
85
+ $('.star').removeClass('hover-active');
86
+ $('.star').each(function(index) {
87
+ if ($(this).data('rating') <= rating) {
88
+ $(this).addClass('hover-active');
89
+ }
90
+ });
91
+ },
92
+ function() {
93
+ $('.star').removeClass('hover-active');
94
+ }
95
+ );
96
+ });
97
+
98
+ const sendFeedback = async function(message) {
99
+ const activeStars = $('.star.active').length;
100
+ const data = {
101
+ "external_user_id": window.externalUserId,
102
+ "message": message,
103
+ "rating": activeStars,
104
+ "space": "spaces/AAQAupQldd4", // Este valor podría necesitar ser dinámico
105
+ "type": "MESSAGE_TRIGGER"
106
+ };
107
+ try {
108
+ // Asumiendo que callLLMAPI está definido globalmente en otro archivo (ej. chat_main.js)
109
+ const responseData = await callLLMAPI('/feedback', data, "POST");
110
+ return responseData;
111
+ } catch (error) {
112
+ console.error("Error al enviar feedback:", error);
113
+ return null;
114
+ }
115
+ }
@@ -0,0 +1,85 @@
1
+ $(document).ready(function () {
2
+ const paperclipButton = $('#paperclip-button');
3
+ const viewFilesButtonContainer = $('#view-files-button-container');
4
+ const viewFilesButton = $('#view-files-button');
5
+ const uploadedFilesModalElement = $('#uploadedFilesModal');
6
+ const uploadedFilesModal = uploadedFilesModalElement; // En Bootstrap 3, el elemento jQuery es el modal
7
+ const uploadedFilesList = $('#uploaded-files-list');
8
+
9
+ // Initialize FilePond
10
+ window.filePond = FilePond.create(
11
+ document.querySelector('#file-upload'), {
12
+ allowMultiple: true,
13
+ labelIdle: '',
14
+ credits: false,
15
+ allowFileSizeValidation: true,
16
+ maxFileSize: '10MB',
17
+ stylePanelLayout: null,
18
+ itemInsertLocation: 'after',
19
+ instantUpload: false,
20
+ });
21
+
22
+ $('.filepond--root').hide(); // Ocultar la UI de FilePond
23
+
24
+ // Función para actualizar la visibilidad del icono "ver archivos"
25
+ function updateFileIconsVisibility() {
26
+ const files = filePond.getFiles();
27
+ if (files.length > 0) {
28
+ viewFilesButtonContainer.show();
29
+ } else {
30
+ viewFilesButtonContainer.hide();
31
+ if (uploadedFilesModalElement.hasClass('in')) { // Si el modal está abierto y no hay archivos, ciérralo
32
+ uploadedFilesModal.modal('hide');
33
+ }
34
+ }
35
+ }
36
+
37
+ // Función para poblar el modal con los archivos y botones de eliminar
38
+ function populateFilesModal() {
39
+ uploadedFilesList.empty(); // Limpiar lista anterior
40
+ const files = filePond.getFiles();
41
+
42
+ if (files.length === 0) {
43
+ uploadedFilesList.append('<li class="list-group-item">No hay archivos adjuntos.</li>');
44
+ return;
45
+ }
46
+
47
+ files.forEach(file => {
48
+ const listItem = $(`
49
+ <li class="list-group-item d-flex justify-content-between align-items-center">
50
+ <span class="file-name-modal">${file.filename}</span>
51
+ <button type="button" class="btn btn-sm btn-outline-danger remove-file-btn" data-file-id="${file.id}" title="Eliminar archivo">
52
+ <i class="bi bi-trash-fill"></i>
53
+ </button>
54
+ </li>
55
+ `);
56
+ uploadedFilesList.append(listItem);
57
+ });
58
+ }
59
+
60
+ // Event listeners de FilePond
61
+ window.filePond.on('addfile', () => updateFileIconsVisibility());
62
+ window.filePond.on('removefile', () => {
63
+ updateFileIconsVisibility();
64
+ if (uploadedFilesModalElement.hasClass('in')) {
65
+ populateFilesModal();
66
+ }
67
+ });
68
+
69
+ // Event listeners de los botones de la UI
70
+ paperclipButton.on('click', () => window.filePond.browse());
71
+ viewFilesButton.on('click', () => {
72
+ populateFilesModal();
73
+ uploadedFilesModal.modal('show');
74
+ });
75
+ uploadedFilesList.on('click', '.remove-file-btn', function () {
76
+ const fileIdToRemove = $(this).data('file-id');
77
+ if (fileIdToRemove) {
78
+ window.filePond.removeFile(fileIdToRemove);
79
+ }
80
+ });
81
+
82
+ // Inicializar visibilidad al cargar
83
+ updateFileIconsVisibility();
84
+ });
85
+
@@ -0,0 +1,117 @@
1
+ $(document).ready(function () {
2
+ // Evento para abrir el modal de historial
3
+ $('#history-button').on('click', function() {
4
+ loadHistory();
5
+ $('#historyModal').modal('show');
6
+ });
7
+
8
+ // Variables globales para el historial
9
+ let historyData = [];
10
+
11
+ // Función para cargar el historial
12
+ async function loadHistory() {
13
+ const historyLoading = $('#history-loading');
14
+ const historyError = $('#history-error');
15
+ const historyContent = $('#history-content');
16
+
17
+ // Mostrar loading
18
+ historyLoading.show();
19
+ historyError.hide();
20
+ historyContent.hide();
21
+
22
+ try {
23
+ const data = {
24
+ external_user_id: window.externalUserId
25
+ };
26
+
27
+ const responseData = await callLLMAPI("/history", data, "POST");
28
+
29
+ if (responseData && responseData.history) {
30
+ // Guardar datos globalmente
31
+ historyData = responseData.history;
32
+
33
+ // Mostrar todos los datos
34
+ displayAllHistory();
35
+
36
+ // Mostrar contenido
37
+ historyContent.show();
38
+ } else {
39
+ throw new Error('No se recibieron datos del historial');
40
+ }
41
+ } catch (error) {
42
+ console.error("Error al cargar historial:", error);
43
+ const errorHtml = `
44
+ <div class="alert alert-danger alert-dismissible show" role="alert">
45
+ <strong>Error al cargar el historial:</strong> ${error.message}
46
+ <button type="button" class="close" data-dismiss="alert">
47
+ <span>&times;</span>
48
+ </button>
49
+ </div>
50
+ `;
51
+ historyError.html(errorHtml).show();
52
+ } finally {
53
+ historyLoading.hide();
54
+ }
55
+ }
56
+
57
+ // Función para mostrar todo el historial
58
+ function displayAllHistory() {
59
+ const historyTableBody = $('#history-table-body');
60
+
61
+ // Limpiar tabla
62
+ historyTableBody.empty();
63
+
64
+ // Filtrar solo consultas que son strings simples (no objetos JSON)
65
+ const filteredHistory = historyData.filter(item => {
66
+ try {
67
+ // Intentar parsear como JSON
68
+ const parsed = JSON.parse(item.query);
69
+ // Si se puede parsear y es un objeto, filtrarlo
70
+ return false;
71
+ } catch (e) {
72
+ // Si no se puede parsear, es un string simple, incluirlo
73
+ return true;
74
+ }
75
+ });
76
+
77
+ // Poblar tabla solo con las consultas filtradas
78
+ filteredHistory.forEach((item, index) => {
79
+ const row = $(`
80
+ <tr>
81
+ <td>${index + 1}</td>
82
+ <td>${formatDate(item.created_at)}</td>
83
+ <td class="query-cell" style="cursor: pointer;" title="Haz clic para copiar esta consulta al chat">${item.query}</td>
84
+ </tr>
85
+ `);
86
+ historyTableBody.append(row);
87
+ });
88
+
89
+ // Agregar evento de clic a las celdas de consulta
90
+ historyTableBody.on('click', '.query-cell', function() {
91
+ const queryText = $(this).text();
92
+
93
+ // Copiar el texto al textarea del chat
94
+ $('#question').val(queryText);
95
+
96
+ // Cerrar el modal
97
+ $('#historyModal').modal('hide');
98
+
99
+ // Hacer focus en el textarea para que el usuario pueda editar si lo desea
100
+ $('#question').focus();
101
+ });
102
+ }
103
+
104
+ // Función para formatear fecha
105
+ function formatDate(dateString) {
106
+ const date = new Date(dateString);
107
+ return date.toLocaleDateString('es-CL', {
108
+ day: '2-digit',
109
+ month: '2-digit',
110
+ year: 'numeric',
111
+ hour: '2-digit',
112
+ minute: '2-digit'
113
+ });
114
+ }
115
+
116
+ });
117
+