iatoolkit 0.3.8__py3-none-any.whl → 0.4.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.

iatoolkit/__init__.py CHANGED
@@ -23,6 +23,7 @@ from services.document_service import DocumentService
23
23
  from services.search_service import SearchService
24
24
  from repositories.profile_repo import ProfileRepo
25
25
  from repositories.llm_query_repo import LLMQueryRepo
26
+ from services.query_service import QueryService
26
27
  from repositories.database_manager import DatabaseManager
27
28
  from infra.call_service import CallServiceClient
28
29
  from common.util import Utility
@@ -40,6 +41,7 @@ __all__ = [
40
41
  'Dispatcher',
41
42
  'DocumentService',
42
43
  'SearchService',
44
+ 'QueryService',
43
45
  'ProfileRepo',
44
46
  'LLMQueryRepo',
45
47
  'DatabaseManager',
iatoolkit/base_company.py CHANGED
@@ -43,5 +43,11 @@ class BaseCompany(ABC):
43
43
  def get_metadata_from_filename(self, filename: str) -> dict:
44
44
  raise NotImplementedError("La subclase debe implementar el método get_query_context()")
45
45
 
46
+ def register_cli_commands(self, app):
47
+ """
48
+ optional method for a company definition of it's cli commands
49
+ """
50
+ pass
51
+
46
52
  def unsupported_operation(self, tag):
47
53
  raise NotImplementedError(f"La operación '{tag}' no está soportada por esta empresa.")
@@ -0,0 +1,77 @@
1
+ import click
2
+ import logging
3
+ from iatoolkit import IAToolkit
4
+ from services.dispatcher_service import Dispatcher
5
+ from services.profile_service import ProfileService
6
+
7
+ def register_core_commands(app):
8
+ """Registra los comandos CLI del núcleo de IAToolkit."""
9
+
10
+ @app.cli.command("setup-all-companies")
11
+ def setup_all_companies():
12
+ """🗄️ Inicializa todas las compañías registradas en la base de datos."""
13
+ try:
14
+ dispatcher = IAToolkit.get_instance().get_injector().get(Dispatcher)
15
+ click.echo("🚀 Inicializando base de datos y compañías...")
16
+ dispatcher.setup_all_companies()
17
+ click.echo("✅ Base de datos y compañías inicializadas correctamente.")
18
+ except Exception as e:
19
+ logging.exception(e)
20
+ click.echo(f"❌ Error: {e}")
21
+
22
+ @app.cli.command("setup-company")
23
+ @click.argument("company_short_name")
24
+ def setup_company(company_short_name: str):
25
+ """⚙️ Genera una nueva API key para una compañía ya registrada."""
26
+ try:
27
+ profile_service = IAToolkit.get_instance().get_injector().get(ProfileService)
28
+ click.echo(f"🔑 Generando API key para '{company_short_name}'...")
29
+ result = profile_service.new_api_key(company_short_name)
30
+
31
+ if 'error' in result:
32
+ click.echo(f"❌ Error: {result['error']}")
33
+ click.echo("👉 Asegúrate de que el nombre de la compañía es correcto y está registrada.")
34
+ else:
35
+ click.echo("✅ ¡Configuración lista! Agrega esta variable a tu entorno:")
36
+ click.echo(f"IATOOLKIT_API_KEY={result['api-key']}")
37
+ except Exception as e:
38
+ logging.exception(e)
39
+ click.echo(f"❌ Ocurrió un error inesperado durante la configuración: {e}")
40
+
41
+ @app.cli.command("encrypt-key")
42
+ @click.argument("key")
43
+ def api_key(key: str):
44
+ from common.util import Utility
45
+
46
+ util = IAToolkit.get_instance().get_injector().get(Utility)
47
+ try:
48
+ encrypt_key = util.encrypt_key(key)
49
+ click.echo(f'la clave encriptada es: {encrypt_key} \n')
50
+ except Exception as e:
51
+ logging.exception(e)
52
+ click.echo(f"Error: {str(e)}")
53
+
54
+ @app.cli.command("exec-tasks")
55
+ @click.argument("company_short_name")
56
+ def exec_pending_tasks(company_short_name: str):
57
+ from services.tasks_service import TaskService
58
+ task_service = IAToolkit.get_instance().get_injector().get(TaskService)
59
+
60
+ try:
61
+ result = task_service.trigger_pending_tasks(company_short_name)
62
+ click.echo(result['message'])
63
+ except Exception as e:
64
+ logging.exception(e)
65
+ click.echo(f"Error: {str(e)}")
66
+
67
+ @app.cli.command("load")
68
+ def load_documents():
69
+ from services.load_documents_service import LoadDocumentsService
70
+
71
+ load_documents_service = IAToolkit.get_instance().get_injector().get(LoadDocumentsService)
72
+ try:
73
+ result = load_documents_service.load()
74
+ click.echo(result['message'])
75
+ except Exception as e:
76
+ logging.exception(e)
77
+ click.echo(f"Error: {str(e)}")
@@ -46,6 +46,10 @@ class CompanyRegistry:
46
46
 
47
47
  return self._company_instances.copy()
48
48
 
49
+ def get_all_company_instances(self) -> Dict[str, BaseCompany]:
50
+ """Devuelve un diccionario con todas las instancias de empresas creadas."""
51
+ return self._company_instances.copy()
52
+
49
53
  def get_registered_companies(self) -> Dict[str, Type[BaseCompany]]:
50
54
  return self._company_classes.copy()
51
55
 
iatoolkit/iatoolkit.py CHANGED
@@ -15,7 +15,6 @@ from urllib.parse import urlparse
15
15
  import redis
16
16
  import logging
17
17
  import os
18
- import click
19
18
  from typing import Optional, Dict, Any
20
19
  from repositories.database_manager import DatabaseManager
21
20
  from injector import Binder, singleton, Injector
@@ -319,75 +318,29 @@ class IAToolkit:
319
318
  Bcrypt(self.app)
320
319
 
321
320
  def _setup_cli_commands(self):
322
- """⌨️ Configura comandos CLI básicos"""
321
+ from iatoolkit.cli_commands import register_core_commands
323
322
  from services.dispatcher_service import Dispatcher
324
- from services.profile_service import ProfileService
323
+ from iatoolkit.company_registry import get_company_registry
324
+
325
+ # 1. Register core commands
326
+ register_core_commands(self.app)
327
+ logging.info("✅ Comandos CLI del núcleo registrados.")
328
+
329
+ # 2. Register company-specific commands
330
+ try:
331
+ # Get the dispatcher, which holds the company instances
332
+ dispatcher = self.get_injector().get(Dispatcher)
333
+ registry = get_company_registry()
334
+
335
+ # Iterate through the registered company names
336
+ for company_name in registry.get_registered_companies():
337
+ company_instance = dispatcher.get_company_instance(company_name)
338
+ if company_instance:
339
+ company_instance.register_cli_commands(self.app)
340
+ logging.info(f"✅ Comandos CLI para la compañía '{company_name}' registrados.")
325
341
 
326
- @self.app.cli.command("setup_all_companies")
327
- def setup_all_companies():
328
- """🗄️ Inicializa la base de datos del sistema"""
329
- try:
330
- dispatcher = self.get_injector().get(Dispatcher)
331
-
332
- click.echo("🚀 Inicializando base de datos...")
333
- dispatcher.setup_all_companies()
334
- click.echo("✅ Base de datos inicializada correctamente")
335
-
336
- except Exception as e:
337
- logging.exception(e)
338
- click.echo(f"❌ Error: {e}")
339
-
340
-
341
- @self.app.cli.command("setup-company")
342
- @click.argument("company_short_name")
343
- def setup_company(company_short_name: str):
344
- """⚙️ Ejecuta el proceso de configuración para una nueva empresa."""
345
- try:
346
- # step 1: init the database
347
- dispatcher = self.get_injector().get(Dispatcher)
348
- click.echo("🚀 step 1 of 2: init companies in the database...")
349
- dispatcher.setup_all_companies()
350
- click.echo("✅ database is ready.")
351
-
352
- # step 2: generate the api key
353
- profile_service = self.get_injector().get(ProfileService)
354
- click.echo(f"🔑 step 2 of 2: generating api-key for use in '{company_short_name}'...")
355
- result = profile_service.new_api_key(company_short_name)
356
-
357
- if 'error' in result:
358
- click.echo(f"❌ Error in step 2: {result['error']}")
359
- click.echo("👉 Make sure company name is correct and it's initialized in your app.")
360
- else:
361
- click.echo("Configuration es ready, add this variable to your environment")
362
- click.echo(f"IATOOLKIT_API_KEY={result['api-key']}")
363
-
364
- except Exception as e:
365
- logging.exception(e)
366
- click.echo(f"❌ Ocurrió un error inesperado durante la configuración: {e}")
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}")
342
+ except Exception as e:
343
+ logging.error(f"❌ Error durante el registro de comandos de compañías: {e}")
391
344
 
392
345
  def _setup_context_processors(self):
393
346
  # Configura context processors para templates
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.3.8
3
+ Version: 0.4.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -1,7 +1,8 @@
1
- iatoolkit/__init__.py,sha256=JdcXIcvFFTMy2XI9ccEws_pCklilDkPPEb7RaQNf7oY,1444
2
- iatoolkit/base_company.py,sha256=gIFaMbQcZ5RAegfNxpjhFLacnOtCvB3sBiXpMtjfM1w,1859
3
- iatoolkit/company_registry.py,sha256=cRaez-VBo1icnUNKmkQqo_Xlr8UKWFoYEMZ70XP6Jgk,2702
4
- iatoolkit/iatoolkit.py,sha256=OKGh5bYQAlyBn8_iI5UKgVykD9V0lW9x4wZE5rCSp5A,18054
1
+ iatoolkit/__init__.py,sha256=WImnnjDcaWy8_CoIS4UA2PwqYcMb0dDNUhg-OlkZ2X8,1512
2
+ iatoolkit/base_company.py,sha256=FlB-HFYH8FoTl4nbtsYgfKjkdZtizJbKwXqaosxmRqc,2009
3
+ iatoolkit/cli_commands.py,sha256=oWd5kwDYd0W1Lcpuk3N2cEnusPAVefaCrYveMQ1zDvY,3223
4
+ iatoolkit/company_registry.py,sha256=HnDpVyCc41OAn-exVF53b_HMES7GelWZcvxR39S_nI4,2900
5
+ iatoolkit/iatoolkit.py,sha256=OwlGujwtNLBYtfZuCpcX_yzrgB8BVo9Jfh72owM8FFc,15651
5
6
  iatoolkit/system_prompts/arquitectura.prompt,sha256=2W-7NWy6P6y1Gh5_-zD1iK-BWq1Siu8TuvGCouP67bQ,1267
6
7
  iatoolkit/system_prompts/format_styles.prompt,sha256=MSMe1qvR3cF_0IbFshn8R0z6Wx6VCHQq1p37rpu5wwk,3576
7
8
  iatoolkit/system_prompts/query_main.prompt,sha256=Eu5VOQzUygJ45Ct1WKYGbi0JMltgI6FQIZWlGmN1bdk,3214
@@ -9,7 +10,7 @@ iatoolkit/system_prompts/sql_rules.prompt,sha256=y4nURVnb9AyFwt-lrbMNBHHtZlhk6kC
9
10
  services/__init__.py,sha256=fSvSfIcPW1dHwTBY1hQ5dBEhaoorzk_GzR4G46gD8tY,173
10
11
  services/api_service.py,sha256=InIKTc64BWcp4U4tYKHz28x4ErPxIfvR9x3ZlxJZlXs,2911
11
12
  services/benchmark_service.py,sha256=g9JVrmAqIe_iI0D1DwdQ6DJ2_FJRCTndarESNSVfhbw,5907
12
- services/dispatcher_service.py,sha256=wWIw9QwyNZ6yaDbANkNdAkdp-f_EAHbJFegjWDcxTAM,14781
13
+ services/dispatcher_service.py,sha256=jGixvvQ4DTQGZye8aa05q56B6U-s6NaDb6he6UTXmQc,15534
13
14
  services/document_service.py,sha256=sm5QtbrKs2dF9hpLuSLMB-IMWYNBD7yWHv3rd80aD0o,5960
14
15
  services/excel_service.py,sha256=wE9Udbyb96kGRSnZZ6KM2mbE484rKjTEhta9GKKpy-8,3630
15
16
  services/file_processor_service.py,sha256=82UArWtwpr94CAMkkoRP0_nPtoqItymdKSIABS0Xkxw,2943
@@ -18,14 +19,14 @@ services/jwt_service.py,sha256=dC45Sn6FyzdzRiQJnzgkjN3Hy21V1imRxB0hTyWRvlA,3979
18
19
  services/load_documents_service.py,sha256=_-OTUih8Zk0m4dHqAhkE7kAwU2mbz_QoMrOKnrq7ZWs,8821
19
20
  services/mail_service.py,sha256=ystFit1LuYUC4ekYYebyiy1rqYQmxeL6K8h58MxEkOY,2233
20
21
  services/profile_service.py,sha256=vZV0cregZQiPKYcNLaD7xjez2y6-3Mq97cDndC8NL8w,17922
21
- services/prompt_manager_service.py,sha256=g499zeWZODqoDvqQZX6eHWmsWj7oLWkEhge7UV_y8IE,7679
22
+ services/prompt_manager_service.py,sha256=bWG4SIgt0u45PVUfm0xRLbLfKC7bk6uozVHRdkdgCmc,7761
22
23
  services/query_service.py,sha256=zpaDzjzh2HqAG1F2Ap8WHBpfAMVtzZ_6v1JGVEguwvs,15687
23
24
  services/search_service.py,sha256=oJD6WRXCJBD7WUVHWWKxexRkhR8nQSrFtcPV3pFO2KQ,1153
24
25
  services/sql_service.py,sha256=H7CIPpXTcxLXLojD2fBFr_mIAD0PW1vEJhKHLfJi4Hk,1418
25
26
  services/tasks_service.py,sha256=hHJDlcsSOPtEleD6_Vv3pocfxWNmthIhmZSdnoWFpEM,6861
26
27
  services/user_feedback_service.py,sha256=YtCndRBekDEWYEbac431Ksn2gMO5iBrI3WqKK0xtShE,2513
27
28
  services/user_session_context_service.py,sha256=5qn7fqpuiU8KgMpU4M5-iRUsETumz1raBw-EeZLuE1A,3868
28
- iatoolkit-0.3.8.dist-info/METADATA,sha256=ojUeydEjMKJIbnIpXnuYhgzdN3Q0PcWnDf_MbBcojtY,8801
29
- iatoolkit-0.3.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
- iatoolkit-0.3.8.dist-info/top_level.txt,sha256=dqlBbmgo9okD9d_WMR9uYzdup7Rxgj26yFF85jRGeu4,19
31
- iatoolkit-0.3.8.dist-info/RECORD,,
29
+ iatoolkit-0.4.0.dist-info/METADATA,sha256=1muE8emXWndqmPwC3xhtpVYjrFiktvWdWdD_UckbW10,8801
30
+ iatoolkit-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ iatoolkit-0.4.0.dist-info/top_level.txt,sha256=dqlBbmgo9okD9d_WMR9uYzdup7Rxgj26yFF85jRGeu4,19
32
+ iatoolkit-0.4.0.dist-info/RECORD,,
@@ -3,7 +3,6 @@
3
3
  # Todos los derechos reservados.
4
4
  # En trámite de registro en el Registro de Propiedad Intelectual de Chile.
5
5
 
6
- from iatoolkit import current_iatoolkit
7
6
  from common.exceptions import IAToolkitException
8
7
  from services.prompt_manager_service import PromptService
9
8
  from services.api_service import ApiService
@@ -11,10 +10,10 @@ from repositories.llm_query_repo import LLMQueryRepo
11
10
  from repositories.models import Company, Function
12
11
  from services.excel_service import ExcelService
13
12
  from services.mail_service import MailService
14
- from iatoolkit.company_registry import get_company_registry
15
13
  from common.session_manager import SessionManager
16
14
  from common.util import Utility
17
15
  from injector import inject
16
+ from typing import Dict
18
17
  import logging
19
18
  import os
20
19
 
@@ -37,11 +36,10 @@ class Dispatcher:
37
36
  self.system_functions = _FUNCTION_LIST
38
37
  self.system_prompts = _SYSTEM_PROMPT
39
38
 
40
- # Use the global registry
41
- self.company_registry = get_company_registry()
39
+ self._company_registry = None
40
+ self._company_instances = None
42
41
 
43
42
  # load into the dispatcher the configured companies
44
- self.company_classes = {}
45
43
  self.initialize_companies()
46
44
 
47
45
  # run the statrtup logic for all companies
@@ -53,23 +51,40 @@ class Dispatcher:
53
51
  "iat_api_call": self.api_service.call_api
54
52
  }
55
53
 
54
+ @property
55
+ def company_registry(self):
56
+ """Lazy-loads and returns the CompanyRegistry instance."""
57
+ if self._company_registry is None:
58
+ from iatoolkit.company_registry import get_company_registry
59
+ self._company_registry = get_company_registry()
60
+ return self._company_registry
61
+
62
+ @property
63
+ def company_instances(self):
64
+ """Lazy-loads and returns the instantiated company classes."""
65
+ if self._company_instances is None:
66
+ self._company_instances = self.company_registry.get_all_company_instances()
67
+ return self._company_instances
68
+
56
69
  def initialize_companies(self):
70
+ from iatoolkit import current_iatoolkit
57
71
  """
58
72
  Initializes and instantiates all registered company classes.
59
73
  This method should be called *after* the main injector is fully configured
60
74
  and the company registry is populated.
61
75
  """
62
- if self.company_classes: # Prevent re-initialization
76
+ if self.company_registry.get_all_company_instances(): # Check if already instantiated
63
77
  return
64
78
 
65
79
  # ✅ NOW it is safe to get the injector and instantiate companies.
66
80
  injector = current_iatoolkit().get_injector()
67
81
  self.company_registry.set_injector(injector)
68
- self.company_classes = self.company_registry.instantiate_companies()
82
+ self.company_registry.instantiate_companies()
83
+
69
84
 
70
85
  def start_execution(self):
71
86
  """Runs the startup logic for all registered companies."""
72
- for company_name, company_instance in self.company_classes.items():
87
+ for company_name, company_instance in self.company_instances.items():
73
88
  logging.info(f'Starting execution for company: {company_name}')
74
89
  company_instance.start_execution()
75
90
 
@@ -100,14 +115,14 @@ class Dispatcher:
100
115
  i += 1
101
116
 
102
117
  # register in the database every company class
103
- for company in self.company_classes.values():
118
+ for company in self.company_instances.values():
104
119
  company.register_company()
105
120
 
106
121
  def dispatch(self, company_name: str, action: str, **kwargs) -> str:
107
122
  company_key = company_name.lower()
108
123
 
109
- if company_key not in self.company_classes:
110
- available_companies = list(self.company_classes.keys())
124
+ if company_key not in self.company_instances:
125
+ available_companies = list(self.company_instances.keys())
111
126
  raise IAToolkitException(
112
127
  IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
113
128
  f"Empresa '{company_name}' no configurada. Empresas disponibles: {available_companies}"
@@ -117,7 +132,7 @@ class Dispatcher:
117
132
  if action in self.tool_handlers:
118
133
  return self.tool_handlers[action](**kwargs)
119
134
 
120
- company_instance = self.company_classes[company_name]
135
+ company_instance = self.company_instances[company_name]
121
136
  try:
122
137
  return company_instance.handle_request(action, **kwargs)
123
138
  except IAToolkitException as e:
@@ -130,7 +145,7 @@ class Dispatcher:
130
145
  f"Error en function call '{action}': {str(e)}") from e
131
146
 
132
147
  def get_company_context(self, company_name: str, **kwargs) -> str:
133
- if company_name not in self.company_classes:
148
+ if company_name not in self.company_instances:
134
149
  raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
135
150
  f"Empresa no configurada: {company_name}")
136
151
 
@@ -152,7 +167,7 @@ class Dispatcher:
152
167
  filepath = os.path.join(schema_dir, file)
153
168
  company_context += self.util.generate_context_for_schema(schema_name, filepath)
154
169
 
155
- company_instance = self.company_classes[company_name]
170
+ company_instance = self.company_instances[company_name]
156
171
  try:
157
172
  return company_context + company_instance.get_company_context(**kwargs)
158
173
  except Exception as e:
@@ -180,7 +195,7 @@ class Dispatcher:
180
195
  return tools
181
196
 
182
197
  def get_user_info(self, company_name: str, user_identifier: str, is_local_user: bool) -> dict:
183
- if company_name not in self.company_classes:
198
+ if company_name not in self.company_instances:
184
199
  raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
185
200
  f"Empresa no configurada: {company_name}")
186
201
 
@@ -190,7 +205,7 @@ class Dispatcher:
190
205
  raw_user_data = SessionManager.get('user', {})
191
206
  else:
192
207
  # source 2: external company user
193
- company_instance = self.company_classes[company_name]
208
+ company_instance = self.company_instances[company_name]
194
209
  try:
195
210
  raw_user_data = company_instance.get_user_info(user_identifier)
196
211
  except Exception as e:
@@ -226,11 +241,11 @@ class Dispatcher:
226
241
  return normalized_user
227
242
 
228
243
  def get_metadata_from_filename(self, company_name: str, filename: str) -> dict:
229
- if company_name not in self.company_classes:
244
+ if company_name not in self.company_instances:
230
245
  raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
231
246
  f"Empresa no configurada: {company_name}")
232
247
 
233
- company_instance = self.company_classes[company_name]
248
+ company_instance = self.company_instances[company_name]
234
249
  try:
235
250
  return company_instance.get_metadata_from_filename(filename)
236
251
  except Exception as e:
@@ -238,12 +253,16 @@ class Dispatcher:
238
253
  raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
239
254
  f"Error en get_metadata_from_filename de {company_name}: {str(e)}") from e
240
255
 
256
+ def get_company_instance(self, company_name: str):
257
+ """Returns the instance for a given company name."""
258
+ return self.company_instances.get(company_name)
259
+
241
260
  def get_registered_companies(self) -> dict:
242
- """Obtiene todas las empresas registradas (para debugging/admin)"""
261
+ """Gets all registered companies (for debugging/admin purposes)"""
243
262
  return {
244
263
  "registered_classes": list(self.company_registry.get_registered_companies().keys()),
245
- "instantiated": list(self.company_classes.keys()),
246
- "count": len(self.company_classes)
264
+ "instantiated": list(self.company_instances.keys()),
265
+ "count": len(self.company_instances)
247
266
  }
248
267
 
249
268
 
@@ -74,7 +74,8 @@ class PromptService:
74
74
  raise IAToolkitException(IAToolkitException.ErrorType.DOCUMENT_NOT_FOUND,
75
75
  f"No se encontró el prompt '{prompt_name}' para la empresa '{company.short_name}'")
76
76
 
77
- absolute_filepath = os.path.join(execution_dir, user_prompt.filename)
77
+ prompt_file = f'companies/{company.short_name}/prompts/{user_prompt.filename}'
78
+ absolute_filepath = os.path.join(execution_dir, prompt_file)
78
79
  if not os.path.exists(absolute_filepath):
79
80
  raise IAToolkitException(IAToolkitException.ErrorType.FILE_IO_ERROR,
80
81
  f"El archivo para el prompt '{prompt_name}' no existe: {absolute_filepath}")