iatoolkit 0.16.7__py3-none-any.whl → 0.18.0__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.

@@ -5,6 +5,26 @@ $(document).ready(function () {
5
5
  $('#historyModal').modal('show');
6
6
  });
7
7
 
8
+ // Evento delegado para el icono de copiar.
9
+ // Se adjunta UNA SOLA VEZ al cuerpo de la tabla y funciona para todas las filas
10
+ // que se añadan dinámicamente.
11
+ $('#history-table-body').on('click', '.copy-query-icon', function() {
12
+ const queryText = $(this).data('query');
13
+
14
+ // Copiar el texto al textarea del chat
15
+ if (queryText) { // Buena práctica: Asegurarse de que el dato no es indefinido
16
+ $('#question').val(queryText);
17
+ autoResizeTextarea($('#question')[0]);
18
+ $('#send-button').removeClass('disabled');
19
+
20
+ // Cerrar el modal
21
+ $('#historyModal').modal('hide');
22
+
23
+ // Hacer focus en el textarea
24
+ $('#question').focus();
25
+ }
26
+ });
27
+
8
28
  // Variables globales para el historial
9
29
  let historyData = [];
10
30
 
@@ -36,16 +56,17 @@ $(document).ready(function () {
36
56
  // Mostrar contenido
37
57
  historyContent.show();
38
58
  } else {
39
- throw new Error('No se recibieron datos del historial');
59
+ throw new Error('La respuesta del servidor no contenía el formato esperado.');
40
60
  }
41
61
  } catch (error) {
42
62
  console.error("Error al cargar historial:", error);
63
+
64
+ const friendlyErrorMessage = "No hemos podido cargar tu historial en este momento. Por favor, cierra esta ventana y vuelve a intentarlo en unos instantes.";
43
65
  const errorHtml = `
44
- <div class="alert alert-branded-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>
66
+ <div class="text-center p-4">
67
+ <i class="bi bi-exclamation-triangle text-danger" style="font-size: 2.5rem; opacity: 0.8;"></i>
68
+ <h5 class="mt-3 mb-2">Ocurrió un Problema</h5>
69
+ <p class="text-muted">${friendlyErrorMessage}</p>
49
70
  </div>
50
71
  `;
51
72
  historyError.html(errorHtml).show();
@@ -61,58 +82,52 @@ $(document).ready(function () {
61
82
  // Limpiar tabla
62
83
  historyTableBody.empty();
63
84
 
64
- // Filtrar solo consultas que son strings simples (no objetos JSON)
85
+ // Filtrar solo consultas que son strings simples
65
86
  const filteredHistory = historyData.filter(item => {
66
87
  try {
67
- // Intentar parsear como JSON
68
- const parsed = JSON.parse(item.query);
69
- // Si se puede parsear y es un objeto, filtrarlo
88
+ JSON.parse(item.query);
70
89
  return false;
71
90
  } catch (e) {
72
- // Si no se puede parsear, es un string simple, incluirlo
73
91
  return true;
74
92
  }
75
93
  });
76
94
 
77
- // Poblar tabla solo con las consultas filtradas
95
+ // Poblar tabla con un método más seguro
78
96
  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
- `);
97
+ const icon = $('<i>').addClass('bi bi-pencil-fill');
98
+
99
+ const link = $('<a>')
100
+ .attr('href', 'javascript:void(0);')
101
+ .addClass('copy-query-icon')
102
+ .attr('title', 'Copiar consulta al chat')
103
+ .data('query', item.query) // Usar .data() es más seguro que un atributo de string
104
+ .append(icon);
105
+
106
+ const row = $('<tr>').append(
107
+ $('<td>').text(index + 1),
108
+ $('<td>').addClass('date-cell').text(formatDate(item.created_at)),
109
+ $('<td>').text(item.query), // Usar .text() para evitar inyección de HTML
110
+ $('<td>').addClass('text-center').append(link)
111
+ );
112
+
86
113
  historyTableBody.append(row);
87
114
  });
88
115
 
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
- $('#send-button').removeClass('disabled');
96
-
97
- // Cerrar el modal
98
- $('#historyModal').modal('hide');
99
-
100
- // Hacer focus en el textarea para que el usuario pueda editar si lo desea
101
- $('#question').focus();
102
- });
116
+ // El event handler ya no se adjunta aquí.
103
117
  }
104
118
 
105
- // Función para formatear fecha
119
+ // Función para formatear fecha (sin cambios)
106
120
  function formatDate(dateString) {
107
121
  const date = new Date(dateString);
108
- return date.toLocaleDateString('es-CL', {
109
- day: '2-digit',
110
- month: '2-digit',
111
- year: 'numeric',
112
- hour: '2-digit',
113
- minute: '2-digit'
114
- });
115
- }
116
122
 
117
- });
123
+ const padTo2Digits = (num) => num.toString().padStart(2, '0');
118
124
 
125
+ const day = padTo2Digits(date.getDate());
126
+ const month = padTo2Digits(date.getMonth() + 1);
127
+ const year = date.getFullYear();
128
+ const hours = padTo2Digits(date.getHours());
129
+ const minutes = padTo2Digits(date.getMinutes());
130
+
131
+ return `${day}-${month}-${year} ${hours}:${minutes}`;
132
+ }
133
+ });
@@ -314,9 +314,21 @@ const callLLMAPI = async function(apiPath, data, method, timeoutMs = 500000) {
314
314
  clearTimeout(timeoutId);
315
315
 
316
316
  if (!response.ok) {
317
- const errorData = await response.json();
318
- const endpointError = $('<div>').addClass('error-section').append(`<p>${errorData.error_message || 'Unknown server error'}</p>`);
319
- displayBotMessage(endpointError);
317
+ try {
318
+ // Intentamos leer el error como JSON, que es el formato esperado de nuestra API.
319
+ const errorData = await response.json();
320
+ const errorMessage = errorData.error_message || 'Error desconocido del servidor.';
321
+ const errorIcon = '<i class="bi bi-exclamation-triangle"></i>';
322
+ const endpointError = $('<div>').addClass('error-section').html(errorIcon + `<p>${errorMessage}</p>`);
323
+ displayBotMessage(endpointError);
324
+ } catch (e) {
325
+ // Si response.json() falla, es porque el cuerpo no era JSON (ej. un 502 con HTML).
326
+ // Mostramos un error genérico y más claro para el usuario.
327
+ const errorMessage = `Error de comunicación con el servidor (${response.status}). Por favor, intente de nuevo más tarde.`;
328
+ const errorIcon = '<i class="bi bi-exclamation-triangle"></i>';
329
+ const infrastructureError = $('<div>').addClass('error-section').html(errorIcon + `<p>${errorMessage}</p>`);
330
+ displayBotMessage(infrastructureError);
331
+ }
320
332
  return null;
321
333
  }
322
334
  return await response.json();
@@ -325,7 +337,9 @@ const callLLMAPI = async function(apiPath, data, method, timeoutMs = 500000) {
325
337
  if (error.name === 'AbortError') {
326
338
  throw error; // Re-throw to be handled by handleChatMessage
327
339
  } else {
328
- const commError = $('<div>').addClass('error-section').append(`<p>Connection error: ${error.message}</p>`);
340
+ const friendlyMessage = "Ocurrió un error de red. Por favor, inténtalo de nuevo en unos momentos.";
341
+ const errorIcon = '<i class="bi bi-exclamation-triangle"></i>';
342
+ const commError = $('<div>').addClass('error-section').html(errorIcon + `<p>${friendlyMessage}</p>`);
329
343
  displayBotMessage(commError);
330
344
  }
331
345
  return null;
@@ -123,32 +123,31 @@
123
123
  word-wrap: break-word;
124
124
  padding-top: 0.5em;
125
125
  }
126
-
127
126
  .error-section {
128
127
  align-self: flex-start;
129
128
  max-width: 75%;
130
- min-width: fit-content;
131
- width: fit-content;
132
- margin-top: 10px;
129
+ min-width: 250px;
130
+
131
+ color: var(--brand-danger-text, #842029); /* Color de texto de error de la marca */
132
+ background-color: var(--brand-danger-bg, #f8d7da); /* Fondo de error de la marca */
133
+ border: 1px solid var(--brand-danger-border, #f5c2c7); /* Borde de error de la marca */
134
+ font-style: italic;
135
+ font-size: 0.9rem;
133
136
  display: flex;
134
- align-items: flex-start;
135
- gap: 12px;
136
- background-color: #fff0f0;
137
- color: #5c0f0f;
138
- border: 1px solid #ffcccc;
139
- padding: 12px 18px;
140
- border-radius: 0 12px 12px 12px;
141
- font-family: Arial, sans-serif;
142
- font-size: 15px;
143
- line-height: 1.5;
144
- word-wrap: break-word;
145
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
137
+ align-items: center;
138
+ justify-content: start;
139
+ margin: 10px 0;
140
+ padding: 10px 15px; /* Un poco más de padding lateral */
141
+ opacity: 0.9;
142
+ border-radius: 8px; /* Bordes redondeados */
143
+ word-wrap: break-word; /* Asegura que el texto no se desborde */
146
144
  }
147
145
 
148
146
  .error-section i {
149
- color: #d32f2f;
150
- font-size: 1.2em;
151
- padding-top: 2px;
147
+ color: var(--brand-danger-color, #dc3545); /* Color del icono, el rojo principal */
148
+ font-size: 1.2rem; /* Tamaño del icono */
149
+ margin-right: 10px; /* Espacio entre el icono y el texto */
150
+ flex-shrink: 0; /* Evita que el icono se encoja */
152
151
  }
153
152
 
154
153
  #question {
@@ -97,6 +97,24 @@
97
97
  width: auto; /* Columna de la consulta - ocupa el resto */
98
98
  }
99
99
 
100
+ /* Evita el salto de línea en la celda de la fecha */
101
+ #historyModal .date-cell {
102
+ white-space: nowrap;
103
+ }
104
+
105
+ /* Estilo para el icono de copiar/editar en cada fila */
106
+ #historyModal .copy-query-icon {
107
+ color: var(--brand-secondary-color, #6c757d); /* Usa el color secundario de la marca */
108
+ text-decoration: none;
109
+ opacity: 0.6;
110
+ transition: opacity 0.2s ease-in-out;
111
+ }
112
+
113
+ #historyModal .copy-query-icon:hover {
114
+ opacity: 1; /* El icono se vuelve completamente opaco al pasar el ratón */
115
+ cursor: pointer; /* Asegura que el cursor cambie a una mano */
116
+ }
117
+
100
118
  /* ######################################################### */
101
119
  /* Modal de feedback */
102
120
  /* ######################################################### */
@@ -17,7 +17,8 @@
17
17
  <span style="{{ branding.primary_text_style }}">
18
18
  {{ branding.name }}
19
19
  </span>
20
- <span class="ms-2" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Powered by IAToolkit ({{ iatoolkit_version }})">
20
+ <span class="ms-2" data-bs-toggle="tooltip" data-bs-placement="bottom"
21
+ title="Powered by IAToolkit ({{ iatoolkit_version }})">
21
22
  <i class="bi bi-info-circle" style="color: {{ branding.header_text_color }}; opacity: 0.7; font-size: 0.9rem;"></i>
22
23
  </span>
23
24
  </div>
@@ -80,22 +80,19 @@
80
80
  </div>
81
81
  <p class="mt-2">Cargando historial...</p>
82
82
  </div>
83
- <div id="history-error" style="display: none;" class="alert alert-danger">
83
+ <div id="history-error" style="display: none;">
84
84
  <!-- Los errores se mostrarán aquí -->
85
85
  </div>
86
86
  <div id="history-content" style="display: none;">
87
- <!-- Texto explicativo -->
88
- <div class="alert alert-branded-info mb-3" role="alert">
89
- <i class="bi bi-info-circle me-2"></i>
90
- <strong>Tip:</strong> Haz clic en cualquier pregunta del historial para copiarla automáticamente al área de texto.
91
- </div>
87
+
92
88
  <div class="table-responsive">
93
89
  <table class="table table-striped table-hover">
94
90
  <thead class="thead-branded">
95
91
  <tr>
96
- <th scope="col">#</th>
92
+ <th scope="col" style="width: 5%;">#</th>
97
93
  <th scope="col">Fecha</th>
98
94
  <th scope="col">Consulta</th>
95
+ <th scope="col" style="width: 5%;"></th>
99
96
  </tr>
100
97
  </thead>
101
98
  <tbody id="history-table-body">
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.16.7
3
+ Version: 0.18.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -65,11 +65,11 @@ iatoolkit/static/images/logo_umayor.png,sha256=FHr1wvI8uDn1YRbRcLSRLBOc0mYusHx9U
65
65
  iatoolkit/static/images/upload.png,sha256=zh5FiINURpaWZQF86bF_gALBX4W1c4aLp5wPQO9xGXI,296
66
66
  iatoolkit/static/js/chat_feedback.js,sha256=_izl49hFEUZYREcJoaPukpTs0YjDgJYUu-QfPt5Ll2s,4398
67
67
  iatoolkit/static/js/chat_filepond.js,sha256=mzXafm7a506EpM37KATTK3zvAswO1E0KSUY1vKbwuRc,3163
68
- iatoolkit/static/js/chat_history.js,sha256=G01rKSXOpLpIavycGPbfpfYg5vmPrLhkHYbCLhY3_zs,3964
69
- iatoolkit/static/js/chat_main.js,sha256=BLKN5a3xP2uu0z6iF6qmgIpT1vClaZf3apcAVQBhU0g,16229
70
- iatoolkit/static/styles/chat_iatoolkit.css,sha256=TbdviimueZjOKVH5FFSjfIqJvLJJt1XGFRwUJgsIP5M,10887
68
+ iatoolkit/static/js/chat_history.js,sha256=79xI8lRdb7Ja4c1qqhv-ZVyJnViZWFPhX6BK3CwLbbI,4736
69
+ iatoolkit/static/js/chat_main.js,sha256=mJH3mWn_-4xeBhGdHiQFDDp7l2_OdWhXc7r1v_A22pE,17313
70
+ iatoolkit/static/styles/chat_iatoolkit.css,sha256=36987PwwNc_H86zCHZMllLT8SPAo7v2b60jC8p0LFEM,11271
71
71
  iatoolkit/static/styles/chat_info.css,sha256=17DbgoNYE21VYWfb5L9-QLCpD2R1idK4imKRLwXtJLY,1058
72
- iatoolkit/static/styles/chat_modal.css,sha256=pE7JY5D63Ds_d2FKdmxym4sevvg-2Mf7yo-gB7KA9vE,3730
72
+ iatoolkit/static/styles/chat_modal.css,sha256=mdfjrJtmUn3O9rKwIGjJc-oSNmJGnzUY1aAJqEfPh38,4301
73
73
  iatoolkit/static/styles/llm_output.css,sha256=AlxgRSOleeCk2dLAqFWVaQ-jwZiJjcpC5rHuUv3T6VU,2312
74
74
  iatoolkit/system_prompts/format_styles.prompt,sha256=MSMe1qvR3cF_0IbFshn8R0z6Wx6VCHQq1p37rpu5wwk,3576
75
75
  iatoolkit/system_prompts/query_main.prompt,sha256=w_9ybgWgiQH4V_RbAXqsvz0M7oOuiyhxcwf-D0CgfA4,3017
@@ -77,8 +77,8 @@ iatoolkit/system_prompts/sql_rules.prompt,sha256=y4nURVnb9AyFwt-lrbMNBHHtZlhk6kC
77
77
  iatoolkit/templates/about.html,sha256=ciC08grUVz5qLzdzDDqDX31xirg5PrJIRYabWpV9oA8,294
78
78
  iatoolkit/templates/base.html,sha256=TojvSnVvXkTe7Kpt_BBWoXFfZN6dveKD0VqQjUOXdgU,2212
79
79
  iatoolkit/templates/change_password.html,sha256=DFfQSFcZ2YJZNFis2IXfzEKStxTf4i9f4eQ_6GiyNs8,2342
80
- iatoolkit/templates/chat.html,sha256=N_DMuh2YwunlAkHalzUt8Soh3kFIaWBlN1hRqa3zDWM,9477
81
- iatoolkit/templates/chat_modals.html,sha256=tMyVPiZ904nm7wXFN3TWf4CTgOSgtJA7TRhCPmawaj0,5795
80
+ iatoolkit/templates/chat.html,sha256=HpQxZHqlPN6iOuMaWQPOlrqyC7Aib3AYpboRAokLHZk,9491
81
+ iatoolkit/templates/chat_modals.html,sha256=ngKk0L8qnWteBDLAqCKv8-55LWNH3-HwVyk2of6ylWo,5510
82
82
  iatoolkit/templates/error.html,sha256=BNF-7z8AYL5vF4ZMUFMrOBt8c85kCFrm9qSHn9EiHWg,540
83
83
  iatoolkit/templates/forgot_password.html,sha256=1lUbKg9CKnQdnySplceY_pibwYne1-mOlM38fqI1kW8,1563
84
84
  iatoolkit/templates/header.html,sha256=179agI7rnYwP_rvJNXIiVde5E8Ec5649_XKq6eew2Hk,1263
@@ -104,7 +104,7 @@ iatoolkit/views/tasks_review_view.py,sha256=keLsLCyOTTlcoIapnB_lbuSvLwrPVZVpBiFC
104
104
  iatoolkit/views/tasks_view.py,sha256=a3anTXrJTTvbQuc6PSpOzidLKQFL4hWa7PI2Cppcz8w,4110
105
105
  iatoolkit/views/user_feedback_view.py,sha256=G37zmP8P4LvZrSymNJ5iFXhLZg1A3BEwRfTpH1Iam5w,2652
106
106
  iatoolkit/views/verify_user_view.py,sha256=a3q4wHJ8mKAEmgbNTOcnX4rMikROjOR3mHvCr30qGGA,2351
107
- iatoolkit-0.16.7.dist-info/METADATA,sha256=1_pD9jIOgsd99lhdxCUh_QqCdllBfTmsHALF2RJwnfs,9301
108
- iatoolkit-0.16.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
- iatoolkit-0.16.7.dist-info/top_level.txt,sha256=V_w4QvDx0b1RXiy8zTCrD1Bp7AZkFe3_O0-9fMiwogg,10
110
- iatoolkit-0.16.7.dist-info/RECORD,,
107
+ iatoolkit-0.18.0.dist-info/METADATA,sha256=LhMtK3T52D0dc1QeV-mRyfnpNhQRHDDAwlvz3zrEXiQ,9301
108
+ iatoolkit-0.18.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
+ iatoolkit-0.18.0.dist-info/top_level.txt,sha256=V_w4QvDx0b1RXiy8zTCrD1Bp7AZkFe3_O0-9fMiwogg,10
110
+ iatoolkit-0.18.0.dist-info/RECORD,,