iatoolkit 0.3.6__tar.gz → 0.3.8__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.
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/PKG-INFO +1 -1
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/pyproject.toml +6 -2
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit/base_company.py +7 -2
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit/iatoolkit.py +42 -11
- iatoolkit-0.3.8/src/iatoolkit/system_prompts/arquitectura.prompt +32 -0
- iatoolkit-0.3.8/src/iatoolkit/system_prompts/format_styles.prompt +97 -0
- iatoolkit-0.3.8/src/iatoolkit/system_prompts/query_main.prompt +67 -0
- iatoolkit-0.3.8/src/iatoolkit/system_prompts/sql_rules.prompt +1337 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit.egg-info/PKG-INFO +1 -1
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit.egg-info/SOURCES.txt +4 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/dispatcher_service.py +44 -12
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/history_service.py +1 -1
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/profile_service.py +3 -3
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/prompt_manager_service.py +15 -23
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/query_service.py +9 -7
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/readme.md +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/requirements.txt +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/setup.cfg +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit/__init__.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit/company_registry.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/iatoolkit.egg-info/top_level.txt +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/__init__.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/api_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/benchmark_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/document_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/excel_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/file_processor_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/jwt_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/load_documents_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/mail_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/search_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/sql_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/tasks_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/user_feedback_service.py +0 -0
- {iatoolkit-0.3.6 → iatoolkit-0.3.8}/src/services/user_session_context_service.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "iatoolkit"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.8"
|
|
8
8
|
requires-python = ">=3.11"
|
|
9
9
|
description = "IAToolkit"
|
|
10
10
|
readme = "readme.md"
|
|
@@ -22,4 +22,8 @@ where = ["src"]
|
|
|
22
22
|
include = ["iatoolkit*", "services*"]
|
|
23
23
|
|
|
24
24
|
[tool.setuptools.dynamic]
|
|
25
|
-
dependencies = { file = ["requirements.txt"] }
|
|
25
|
+
dependencies = { file = ["requirements.txt"] }
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.package-data]
|
|
28
|
+
# 'src/system_prompts' relativo al paquete 'iatoolkit'
|
|
29
|
+
iatoolkit = ["system_prompts/*.prompt"]
|
|
@@ -15,14 +15,19 @@ class BaseCompany(ABC):
|
|
|
15
15
|
|
|
16
16
|
@abstractmethod
|
|
17
17
|
# initialize all the database tables needed
|
|
18
|
-
def
|
|
19
|
-
raise NotImplementedError("La subclase debe implementar el método
|
|
18
|
+
def register_company(self):
|
|
19
|
+
raise NotImplementedError("La subclase debe implementar el método create_company()")
|
|
20
20
|
|
|
21
21
|
@abstractmethod
|
|
22
22
|
# get context specific for this company
|
|
23
23
|
def get_company_context(self, **kwargs) -> str:
|
|
24
24
|
raise NotImplementedError("La subclase debe implementar el método get_company_context()")
|
|
25
25
|
|
|
26
|
+
@abstractmethod
|
|
27
|
+
# get context specific for this company
|
|
28
|
+
def get_user_info(self, **kwargs) -> str:
|
|
29
|
+
raise NotImplementedError("La subclase debe implementar el método get_user_info()")
|
|
30
|
+
|
|
26
31
|
@abstractmethod
|
|
27
32
|
# execute the specific action configured in the intent table
|
|
28
33
|
def handle_request(self, tag: str, params: dict) -> dict:
|
|
@@ -19,10 +19,10 @@ import click
|
|
|
19
19
|
from typing import Optional, Dict, Any
|
|
20
20
|
from repositories.database_manager import DatabaseManager
|
|
21
21
|
from injector import Binder, singleton, Injector
|
|
22
|
+
from importlib.metadata import version as _pkg_version, PackageNotFoundError
|
|
22
23
|
|
|
23
|
-
VERSION = "2.0.0"
|
|
24
24
|
|
|
25
|
-
# global variable for
|
|
25
|
+
# global variable for the unique instance of IAToolkit
|
|
26
26
|
_iatoolkit_instance: Optional['IAToolkit'] = None
|
|
27
27
|
|
|
28
28
|
|
|
@@ -53,6 +53,7 @@ class IAToolkit:
|
|
|
53
53
|
self.app = None
|
|
54
54
|
self.db_manager = None
|
|
55
55
|
self._injector = None
|
|
56
|
+
self.version = "0.0.0+dev"
|
|
56
57
|
|
|
57
58
|
@classmethod
|
|
58
59
|
def get_instance(cls) -> 'IAToolkit':
|
|
@@ -69,6 +70,9 @@ class IAToolkit:
|
|
|
69
70
|
Creates, configures, and returns the Flask application instance.
|
|
70
71
|
this is the main entry point for the application factory.
|
|
71
72
|
"""
|
|
73
|
+
if self._initialized and self.app:
|
|
74
|
+
return self.app
|
|
75
|
+
|
|
72
76
|
self._setup_logging()
|
|
73
77
|
|
|
74
78
|
# Step 1: Create the Flask app instance
|
|
@@ -94,7 +98,13 @@ class IAToolkit:
|
|
|
94
98
|
self._setup_cli_commands()
|
|
95
99
|
self._setup_context_processors()
|
|
96
100
|
|
|
97
|
-
|
|
101
|
+
try:
|
|
102
|
+
self.version = _pkg_version("iatoolkit")
|
|
103
|
+
except PackageNotFoundError:
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
logging.info(f"🎉 IAToolkit v{self.version} inicializado correctamente")
|
|
107
|
+
self._initialized = True
|
|
98
108
|
return self.app
|
|
99
109
|
|
|
100
110
|
def _get_config_value(self, key: str, default=None):
|
|
@@ -133,7 +143,7 @@ class IAToolkit:
|
|
|
133
143
|
is_dev = self._get_config_value('FLASK_ENV') == 'development'
|
|
134
144
|
|
|
135
145
|
self.app.config.update({
|
|
136
|
-
'VERSION':
|
|
146
|
+
'VERSION': self.version,
|
|
137
147
|
'SECRET_KEY': self._get_config_value('FLASK_SECRET_KEY', 'iatoolkit-default-secret'),
|
|
138
148
|
'SESSION_COOKIE_SAMESITE': "None" if is_https else "Lax",
|
|
139
149
|
'SESSION_COOKIE_SECURE': is_https,
|
|
@@ -192,9 +202,9 @@ class IAToolkit:
|
|
|
192
202
|
"""🌐 Configura CORS"""
|
|
193
203
|
# Origins por defecto para desarrollo
|
|
194
204
|
default_origins = [
|
|
195
|
-
"http://localhost:3000",
|
|
196
205
|
"http://localhost:5001",
|
|
197
|
-
"http://127.0.0.1:5001"
|
|
206
|
+
"http://127.0.0.1:5001",
|
|
207
|
+
os.getenv('IATOOLKIT_BASE_URL')
|
|
198
208
|
]
|
|
199
209
|
|
|
200
210
|
# Obtener origins adicionales desde configuración/env
|
|
@@ -242,14 +252,12 @@ class IAToolkit:
|
|
|
242
252
|
|
|
243
253
|
def _bind_repositories(self, binder: Binder):
|
|
244
254
|
from repositories.document_repo import DocumentRepo
|
|
245
|
-
from repositories.document_type_repo import DocumentTypeRepo
|
|
246
255
|
from repositories.profile_repo import ProfileRepo
|
|
247
256
|
from repositories.llm_query_repo import LLMQueryRepo
|
|
248
257
|
from repositories.vs_repo import VSRepo
|
|
249
258
|
from repositories.tasks_repo import TaskRepo
|
|
250
259
|
|
|
251
260
|
binder.bind(DocumentRepo, to=DocumentRepo)
|
|
252
|
-
binder.bind(DocumentTypeRepo, to=DocumentTypeRepo)
|
|
253
261
|
binder.bind(ProfileRepo, to=ProfileRepo)
|
|
254
262
|
binder.bind(LLMQueryRepo, to=LLMQueryRepo)
|
|
255
263
|
binder.bind(VSRepo, to=VSRepo)
|
|
@@ -315,8 +323,8 @@ class IAToolkit:
|
|
|
315
323
|
from services.dispatcher_service import Dispatcher
|
|
316
324
|
from services.profile_service import ProfileService
|
|
317
325
|
|
|
318
|
-
@self.app.cli.command("
|
|
319
|
-
def
|
|
326
|
+
@self.app.cli.command("setup_all_companies")
|
|
327
|
+
def setup_all_companies():
|
|
320
328
|
"""🗄️ Inicializa la base de datos del sistema"""
|
|
321
329
|
try:
|
|
322
330
|
dispatcher = self.get_injector().get(Dispatcher)
|
|
@@ -357,6 +365,29 @@ class IAToolkit:
|
|
|
357
365
|
logging.exception(e)
|
|
358
366
|
click.echo(f"❌ Ocurrió un error inesperado durante la configuración: {e}")
|
|
359
367
|
|
|
368
|
+
@self.app.cli.command("populate-sample-db")
|
|
369
|
+
def populate_sample_db():
|
|
370
|
+
from companies.sample_company.sample_company import SampleCompany
|
|
371
|
+
"""📦 Crea y puebla la base de datos de sample_company con datos de prueba."""
|
|
372
|
+
try:
|
|
373
|
+
company_instance = self.get_injector().get(SampleCompany)
|
|
374
|
+
click.echo("🚀 Obteniendo instancia de 'sample_company'...")
|
|
375
|
+
|
|
376
|
+
if not company_instance or not hasattr(company_instance, 'sample_database') or not company_instance.sample_database:
|
|
377
|
+
click.echo("❌ Error: No se pudo obtener la instancia de 'sample_company' o su base de datos no está configurada.")
|
|
378
|
+
click.echo("👉 Asegúrate de que 'sample_company' esté registrada y que la variable de entorno 'SAMPLE_DATABASE_URI' esté definida.")
|
|
379
|
+
return
|
|
380
|
+
|
|
381
|
+
click.echo("⚙️ Creando y poblando la base de datos. Esto puede tardar unos momentos...")
|
|
382
|
+
|
|
383
|
+
company_instance.sample_database.create_database()
|
|
384
|
+
company_instance.sample_database.populate_database()
|
|
385
|
+
|
|
386
|
+
click.echo("✅ Base de datos de 'sample_company' poblada exitosamente.")
|
|
387
|
+
|
|
388
|
+
except Exception as e:
|
|
389
|
+
logging.exception(e)
|
|
390
|
+
click.echo(f"❌ Ocurrió un error inesperado: {e}")
|
|
360
391
|
|
|
361
392
|
def _setup_context_processors(self):
|
|
362
393
|
# Configura context processors para templates
|
|
@@ -364,7 +395,7 @@ class IAToolkit:
|
|
|
364
395
|
def inject_globals():
|
|
365
396
|
return {
|
|
366
397
|
'url_for': url_for,
|
|
367
|
-
'iatoolkit_version':
|
|
398
|
+
'iatoolkit_version': self.version,
|
|
368
399
|
'app_name': 'IAToolkit',
|
|
369
400
|
'user': SessionManager.get('user'),
|
|
370
401
|
'user_company': SessionManager.get('company_short_name'),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Mi app es un chatbot multiempresa, que se conecta
|
|
2
|
+
con datos empresariales por sql y llamadas a endpoints.
|
|
3
|
+
|
|
4
|
+
Es principalmente un backend, pero tambien puede actuar como frontend.
|
|
5
|
+
Cuando actua como backend, los usuarios se identifican como external_user_id
|
|
6
|
+
y el front lo informa en la vista external_login_view.
|
|
7
|
+
|
|
8
|
+
Cuando actua como front y back,
|
|
9
|
+
existe un acceso que simula un usuario externo a través de
|
|
10
|
+
public_chat_view.
|
|
11
|
+
|
|
12
|
+
El otro mecanismo de acceso es con el sistema de usuarios
|
|
13
|
+
integrado a mi app, con tablas propias: user, company, user_company
|
|
14
|
+
y el acceso se hace a través de profile_service.
|
|
15
|
+
|
|
16
|
+
Estos accesos sirven para autentificar las consultas.
|
|
17
|
+
Cada vez que hay un acceso en estos puntos, se llama a query_service
|
|
18
|
+
para que construya el contexto de la empresa y se lo envie al
|
|
19
|
+
llm.
|
|
20
|
+
|
|
21
|
+
Se guarda en session de redis, el response.id generado
|
|
22
|
+
para linkearlo con las consultas futuras (responses api de openai).
|
|
23
|
+
|
|
24
|
+
Por otra parte, las queries ingresan a través de llm_query_view,
|
|
25
|
+
el que autentifica al solicitante y la dirige a query_service.
|
|
26
|
+
|
|
27
|
+
Query_service gestiona los prompts que pueden ser solicitados
|
|
28
|
+
y llama a invoke en openai_client, quien se encarga
|
|
29
|
+
de interactuar con el llm.
|
|
30
|
+
|
|
31
|
+
Una vez terminada la interacción, se graba un registro en la
|
|
32
|
+
tabla llm_queries.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
## **Formato y Estilos de Salida (Reglas Generales)**
|
|
2
|
+
|
|
3
|
+
Las siguientes reglas son **obligatorias** y se deben aplicar a **TODA** la salida, sin excepción.
|
|
4
|
+
|
|
5
|
+
- **Uso de Secciones y Títulos (`<h4>`):**
|
|
6
|
+
Este formato solo debe aplicarse cuando el prompt específico lo pida,
|
|
7
|
+
o cuando la respuesta sea compleja y contenga
|
|
8
|
+
**múltiples puntos distintos** que necesiten ser agrupados bajo
|
|
9
|
+
títulos diferentes.
|
|
10
|
+
|
|
11
|
+
- **IMPORTANTE: Cómo manejar respuestas simples:** Para una respuesta que sea una sola frase o un párrafo corto y directo, **NO** generes una sección.
|
|
12
|
+
|
|
13
|
+
**Ejemplo de lo que NO se debe hacer:**
|
|
14
|
+
`<div class="categoria"><h4>Respuesta</h4>El cliente no tiene ofertas.</div>`
|
|
15
|
+
|
|
16
|
+
**Ejemplo de lo que SÍ se debe hacer:**
|
|
17
|
+
`El cliente no tiene ofertas.`
|
|
18
|
+
|
|
19
|
+
### **Formatos Específicos (Usar solo bajo demanda explícita)**
|
|
20
|
+
|
|
21
|
+
Las siguientes reglas describen el formato a utilizar
|
|
22
|
+
**SÓLO SI el prompt específico te pide generar uno de estos elementos**.
|
|
23
|
+
Si no se te pide una tabla o una lista, ignora estas instrucciones.
|
|
24
|
+
|
|
25
|
+
## Formato para Tablas:**
|
|
26
|
+
Cuando un prompt te solicite explícitamente generar una tabla**,
|
|
27
|
+
debes aplicar el siguiente formato base:
|
|
28
|
+
- Usa las clases `table table-striped table-hover` de Bootstrap como mínimo.
|
|
29
|
+
- cuando generes tablas si la columna es un rut, fecha, un id certificado
|
|
30
|
+
siempre usa la clase **nowrap** en el <th>
|
|
31
|
+
- debes usar class="text-center" o class="text-right"
|
|
32
|
+
si te piden que alguna columna debe centrarse o alinearse a la derecha.
|
|
33
|
+
- Cuando generes una tabla con columnas centradas o alineadas
|
|
34
|
+
a la derecha , **agrega `class="text-center"` o
|
|
35
|
+
`class="text-right"` también en cada `<td>` correspondiente,
|
|
36
|
+
no solo en el `<th>`.
|
|
37
|
+
|
|
38
|
+
Ejemplo:
|
|
39
|
+
<table class="table table-striped table-hover">
|
|
40
|
+
<thead>
|
|
41
|
+
<tr>
|
|
42
|
+
<th class="nowrap">RUT</th>
|
|
43
|
+
<th>Nombre</th>
|
|
44
|
+
<th class="text-center">Estado</th>
|
|
45
|
+
<th class="text-right">Monto</th>
|
|
46
|
+
</tr>
|
|
47
|
+
</thead>
|
|
48
|
+
<tbody>
|
|
49
|
+
<tr>
|
|
50
|
+
<td class="nowrap">12.345.678-9</td>
|
|
51
|
+
<td>ACME Ltda.</td>
|
|
52
|
+
<td class="text-center">Activo</td>
|
|
53
|
+
<td class="text-right">$1.000.000</td>
|
|
54
|
+
</tr>
|
|
55
|
+
</tbody>
|
|
56
|
+
</table>
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Formato para Listas Clave-Valor:**
|
|
60
|
+
Cuando un prompt te solicite explícitamente mostrar datos como una lista de "clave-valor"**,
|
|
61
|
+
debes usar el siguiente formato:
|
|
62
|
+
- La clave (el texto antes de los dos puntos) SIEMPRE debe estar
|
|
63
|
+
envuelta en una etiqueta `<strong>`.
|
|
64
|
+
- Ejemplo:
|
|
65
|
+
`<ul>
|
|
66
|
+
<li><strong>Nombre:</strong> Juan Pérez</li>
|
|
67
|
+
<li><strong>ID de Cliente:</strong> 84321</li>
|
|
68
|
+
</ul>
|
|
69
|
+
`
|
|
70
|
+
|
|
71
|
+
## Formato de Datos dentro de Elementos:**
|
|
72
|
+
Cuando generes tablas o listas que contengan fechas o montos**,
|
|
73
|
+
aplica estas reglas de formato:
|
|
74
|
+
- **Fechas:** `dd-mm-aaaa`
|
|
75
|
+
- **Montos:** Punto (`.`) como separador de miles y coma (`,`)
|
|
76
|
+
como separador decimal.
|
|
77
|
+
si son pesos chilenos coloca el signo $ delante
|
|
78
|
+
si son pesos chilenos ($), nunca pongas decimales
|
|
79
|
+
|
|
80
|
+
## HTML para descarga de archivos
|
|
81
|
+
Siempre que generes un archivo Excel con la función generate_excel,
|
|
82
|
+
debes retornar al usuario un bloque HTML exacto con el enlace de descarga.
|
|
83
|
+
|
|
84
|
+
Usa esta plantilla reemplaza:
|
|
85
|
+
1.{filename} por el nombre real del archivo generado
|
|
86
|
+
2.{download_link} por el link para descargar el archivo generado
|
|
87
|
+
<p>✅ Tu archivo {filename} ha sido generado:</p>
|
|
88
|
+
<a href="{download_link}" download>
|
|
89
|
+
📥 Descargar
|
|
90
|
+
</a>
|
|
91
|
+
|
|
92
|
+
## HTML para envio de emails
|
|
93
|
+
Firma con "Saludos, IAToolkit".
|
|
94
|
+
⚠️ No incluyas ningún enlace de suscripción, texto de "Unsubscribe",
|
|
95
|
+
ni frases sobre administrar preferencias de correo.
|
|
96
|
+
|
|
97
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Eres un asistente que responde preguntas o ejecuta tareas según el contexto de la empresa.
|
|
2
|
+
|
|
3
|
+
### **Nombre de la empresa**
|
|
4
|
+
## Nombre: {{company.name}}
|
|
5
|
+
|
|
6
|
+
### ** Información del usuario que esta consultando este chat**
|
|
7
|
+
Contexto del usuario:
|
|
8
|
+
- Nombre: {{ user_fullname }}
|
|
9
|
+
- Email: {{ user_email }}
|
|
10
|
+
- Tipo de usuario: {% if user_is_local %}Interno{% else %}Externo{% endif %}
|
|
11
|
+
- Empresa: {{ company_name }}
|
|
12
|
+
|
|
13
|
+
{% if user_name %}
|
|
14
|
+
El usuario que consulta se identifica con la variable `user_name` y tiene el
|
|
15
|
+
siguiente valor: {{ user_name }}.
|
|
16
|
+
|
|
17
|
+
Este usuario tiene el rol: {{ user_rol }} en el producto {{ user_product }}.
|
|
18
|
+
|
|
19
|
+
{% else %}
|
|
20
|
+
El usuario que consulta se identifica como: {{ user_id }}
|
|
21
|
+
{% endif %}
|
|
22
|
+
|
|
23
|
+
## Servicios de datos (function calls) disponibles en {{company.name}}:
|
|
24
|
+
{% for service in service_list %}
|
|
25
|
+
# servicio {{ loop.index }}: {{ service.name }}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
|
|
28
|
+
Eres un asistente que responde preguntas sobre empresas y sus clientes.
|
|
29
|
+
|
|
30
|
+
**Reglas obligatorias de contexto:**
|
|
31
|
+
1. Cada vez que el usuario consulte por un cliente (ya sea por RUT o nombre),
|
|
32
|
+
debes memorizarlo y usarlo como cliente de contexto.
|
|
33
|
+
2. Si el usuario hace una pregunta **sin especificar un cliente** (sin RUT ni nombre),
|
|
34
|
+
siempre debes asumir que la pregunta se refiere al **último cliente identificado** en la conversación.
|
|
35
|
+
3. Nunca cambies de cliente de contexto a menos que el usuario especifique uno nuevo.
|
|
36
|
+
4. Si el usuario pregunta por un cliente que no está en tus registros, responde indicando que no tienes información, pero **no borres el contexto anterior**.
|
|
37
|
+
5. No respondas con “no se encontró información del cliente” salvo que nunca se haya identificado ningún cliente antes en la conversación.
|
|
38
|
+
6. No debes incluir explicaciones, comentarios o texto adicional.
|
|
39
|
+
|
|
40
|
+
**IMPORTANTE:**
|
|
41
|
+
Si el usuario no menciona explícitamente nombre ni RUT en la pregunta, SIEMPRE responde usando el **último cliente** del que se obtuvo información.
|
|
42
|
+
|
|
43
|
+
No respondas nunca sobre un cliente anterior si ya se identificó uno nuevo, y nunca pierdas el contexto salvo que el usuario lo cambie explícitamente.
|
|
44
|
+
|
|
45
|
+
### **Instrucciones**
|
|
46
|
+
1. Devuelve siempre la respuesta en formato JSON.
|
|
47
|
+
2. Usa la información de contexto para responder la consulta del usuario de forma clara y concisa.
|
|
48
|
+
Si el contexto o los adjuntos no te proveen información para la respuesta utiliza tu conocimiento propio.
|
|
49
|
+
3. Genera una única `"answer"` que integre la información de todos los servicios relevantes.
|
|
50
|
+
4. En `"aditional_data"`, a menos que se te indique lo contrario retorna un diccionario vacio: {}
|
|
51
|
+
5. El JSON de salida solo puede tener dos llaves: `"answer"` y `"aditional_data"`.
|
|
52
|
+
6. `"answer"` siempre debe contener un unico string con tu respuesta
|
|
53
|
+
7. Devuelve **únicamente** la respuesta en JSON válido, sin texto adicional.
|
|
54
|
+
7. **NO devuelvas el JSON como un string ni como texto escapado.**
|
|
55
|
+
9. **NO incluyas delimitadores como \`\`\`, \`\`\`json, ni comillas alrededor del objeto JSON.**
|
|
56
|
+
10. **NO escribas ninguna explicación ni texto fuera del JSON. Devuelve solo el objeto JSON.**
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### **Ejemplo de salida esperada**
|
|
60
|
+
{
|
|
61
|
+
"answer": "El iPhone 15 Pro está disponible por 1099 USD y tu ticket de soporte está en proceso.",
|
|
62
|
+
"aditional_data": {}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|