iatoolkit 0.7.0__py3-none-any.whl → 0.7.1__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/base_company.py CHANGED
@@ -6,12 +6,66 @@
6
6
  # companies/base_company.py
7
7
  from abc import ABC, abstractmethod
8
8
  from typing import Any
9
+ from repositories.profile_repo import ProfileRepo
10
+ from repositories.llm_query_repo import LLMQueryRepo
11
+ from services.prompt_manager_service import PromptService
12
+ from repositories.models import Company, Function, PromptCategory
13
+ from iatoolkit import IAToolkit
9
14
 
10
15
 
11
16
  class BaseCompany(ABC):
12
- def __init__(self, profile_repo: Any = None, llm_query_repo: Any = None):
13
- self.profile_repo = profile_repo
14
- self.llm_query_repo = llm_query_repo
17
+ def __init__(self):
18
+ # Obtener el inyector global y resolver las dependencias internamente
19
+ injector = IAToolkit.get_instance().get_injector()
20
+ self.profile_repo: ProfileRepo = injector.get(ProfileRepo)
21
+ self.llm_query_repo: LLMQueryRepo = injector.get(LLMQueryRepo)
22
+ self.prompt_service: PromptService = injector.get(PromptService)
23
+ self.company: Company | None = None
24
+
25
+ def _load_company_by_short_name(self, short_name: str) -> Company:
26
+ self.company = self.profile_repo.get_company_by_short_name(short_name)
27
+ return self.company
28
+
29
+ def _create_company(self, name: str, short_name: str) -> Company:
30
+ company_obj = Company(name=name, short_name=short_name, allow_jwt=True)
31
+ self.company = self.profile_repo.create_company(company_obj)
32
+ return self.company
33
+
34
+ def _create_function(self, function_name: str, description: str, params: dict, **kwargs):
35
+ if not self.company:
36
+ raise ValueError("La compañía debe estar definida antes de crear una función.")
37
+
38
+ self.llm_query_repo.create_or_update_function(
39
+ Function(
40
+ company_id=self.company.id,
41
+ name=function_name,
42
+ description=description,
43
+ parameters=params,
44
+ system_function=False,
45
+ **kwargs
46
+ )
47
+ )
48
+
49
+ def _create_prompt_category(self, name: str, order: int) -> PromptCategory:
50
+ if not self.company:
51
+ raise ValueError("La compañía debe estar definida antes de crear una categoría.")
52
+
53
+ return self.llm_query_repo.create_or_update_prompt_category(
54
+ PromptCategory(name=name, order=order, company_id=self.company.id)
55
+ )
56
+
57
+ def _create_prompt(self, prompt_name: str, description: str, category: PromptCategory, order: int, **kwargs):
58
+ if not self.company:
59
+ raise ValueError("La compañía debe estar definida antes de crear un prompt.")
60
+
61
+ self.prompt_service.create_prompt(
62
+ prompt_name=prompt_name,
63
+ description=description,
64
+ order=order,
65
+ company=self.company,
66
+ category=category,
67
+ **kwargs
68
+ )
15
69
 
16
70
  @abstractmethod
17
71
  # initialize all the database tables needed
iatoolkit/cli_commands.py CHANGED
@@ -11,26 +11,12 @@ from services.profile_service import ProfileService
11
11
 
12
12
  def register_core_commands(app):
13
13
  """Registra los comandos CLI del núcleo de IAToolkit."""
14
-
15
- @app.cli.command("setup-all-companies")
16
- def setup_all_companies():
17
- """🗄️ Inicializa todas las compañías registradas en la base de datos."""
18
- try:
19
- dispatcher = IAToolkit.get_instance().get_injector().get(Dispatcher)
20
- click.echo("🚀 Inicializando base de datos y compañías...")
21
- dispatcher.setup_all_companies()
22
- click.echo("✅ Base de datos y compañías inicializadas correctamente.")
23
- except Exception as e:
24
- logging.exception(e)
25
- click.echo(f"❌ Error: {e}")
26
14
 
27
- @app.cli.command("setup-company")
15
+ @app.cli.command("api-key")
28
16
  @click.argument("company_short_name")
29
- def setup_company(company_short_name: str):
17
+ def api_key(company_short_name: str):
30
18
  """⚙️ Genera una nueva API key para una compañía ya registrada."""
31
19
  try:
32
- dispatcher = IAToolkit.get_instance().get_injector().get(Dispatcher)
33
- dispatcher.setup_all_companies()
34
20
  profile_service = IAToolkit.get_instance().get_injector().get(ProfileService)
35
21
  click.echo(f"🔑 Generando API key para '{company_short_name}'...")
36
22
  result = profile_service.new_api_key(company_short_name)
@@ -47,13 +33,13 @@ def register_core_commands(app):
47
33
 
48
34
  @app.cli.command("encrypt-key")
49
35
  @click.argument("key")
50
- def api_key(key: str):
36
+ def encrypt_llm_api_key(key: str):
51
37
  from common.util import Utility
52
38
 
53
39
  util = IAToolkit.get_instance().get_injector().get(Utility)
54
40
  try:
55
41
  encrypt_key = util.encrypt_key(key)
56
- click.echo(f'la clave encriptada es: {encrypt_key} \n')
42
+ click.echo(f'la api-key del LLM encriptada es: {encrypt_key} \n')
57
43
  except Exception as e:
58
44
  logging.exception(e)
59
45
  click.echo(f"Error: {str(e)}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -1,31 +1,30 @@
1
1
  iatoolkit/__init__.py,sha256=GkFxAQHKPifz4Kd8M73Rc8TWRVIxjxkl1N0nsPvb_sU,1743
2
- iatoolkit/base_company.py,sha256=2fG6NqmBOHGRq6LMRNx6xQoa_WqE2coFu8Y4-9V0GpQ,1939
3
- iatoolkit/cli_commands.py,sha256=9zL_UEjaduxVeKXClBbFNzS9I9tKcbmOS695jy94OEY,3013
2
+ iatoolkit/base_company.py,sha256=WmD4o0qFC1n5DW5eRsRsuNfaGot9nxGFcJe3LmibSuE,4259
3
+ iatoolkit/cli_commands.py,sha256=D_MB6wm9cCnrvsn6B2_T-a48KRXOVvGL_-P24wFLEkU,2321
4
4
  iatoolkit/company_registry.py,sha256=tduqt3oV8iDX_IB1eA7KIgvIxE4edTcy-3qZIXh3Lzw,2549
5
5
  iatoolkit/iatoolkit.py,sha256=WgBm34nAeVBCpfDDZD13Pos9xIoRx5viVwxjyYCXAmY,15790
6
6
  iatoolkit/system_prompts/format_styles.prompt,sha256=MSMe1qvR3cF_0IbFshn8R0z6Wx6VCHQq1p37rpu5wwk,3576
7
7
  iatoolkit/system_prompts/query_main.prompt,sha256=w_9ybgWgiQH4V_RbAXqsvz0M7oOuiyhxcwf-D0CgfA4,3017
8
8
  iatoolkit/system_prompts/sql_rules.prompt,sha256=y4nURVnb9AyFwt-lrbMNBHHtZlhk6kC9grYoOhRnrJo,59174
9
9
  services/__init__.py,sha256=5JqK9sZ6jBuK83zDQokUhxQ0wuJJJ9DXB8pYCLkX7X4,102
10
- services/api_service.py,sha256=7FxO9_g-gxuEmYIl5PhgJb7lHVgXJ1btHdH9fDrdhvY,2840
11
10
  services/benchmark_service.py,sha256=_ruKh9YzrTLtR0ZKrRNxqJQW0HdbwWuFz1gfLzJ9owA,5850
12
- services/dispatcher_service.py,sha256=AEaNwROTqUdsZU-RnLylsGQvbiM0540YKKp9PEKKWj4,14098
11
+ services/dispatcher_service.py,sha256=o4XYB04tD_k8MNqgnfSTvtuCc6f4AWaFFbwy9PKEkuo,13983
13
12
  services/document_service.py,sha256=8MsJz0pihM9E9Z92PrPqDgQnpMAmpFrbogXr5HscMWM,5926
14
13
  services/excel_service.py,sha256=ATPaeAvkLwQAkPZ3AKIUpO73RVyRg0D8c6i37_mcql0,3559
15
14
  services/file_processor_service.py,sha256=98yWYF7nIq1nm7nh6IzMmTKaOMTIeqCFWYwXVtV-ZJI,4102
16
15
  services/history_service.py,sha256=j0QCqcIIyw7DBy3GrZrEZNk0I4m-uuRoG5g0Z2RCcOE,1586
17
16
  services/jwt_service.py,sha256=YoZ9h7_o9xBko-arNQv4MbcwnxoSWVNj4VbZmMo_QGY,3908
18
- services/load_documents_service.py,sha256=XQ_Ck1pvj6TfJRIC1cNrWRbLmC0u7E0VJkNWC6L2gI4,7027
17
+ services/load_documents_service.py,sha256=UGfomYz7seWFXawbDuk2t6CyoEr1vggR8vmrCUAeLBg,7190
19
18
  services/mail_service.py,sha256=_67pctxZO46DHnWBip51ayuYtWd4bEoS1kg29ACO7_I,2162
20
19
  services/profile_service.py,sha256=vTK9TvH_2AFdqgL3sGjhck9LyLGIbvdC2USoaRx82G8,17561
21
- services/prompt_manager_service.py,sha256=W-OkG881D7Yyc8PsM2RxDl0nzvTP55bQfl9rHR9yl24,7955
22
- services/query_service.py,sha256=yITLcopc1stgzTkFdrBuF84k_XYsZyoKGue1GfXsb-U,15614
20
+ services/prompt_manager_service.py,sha256=Ed40Iz-Az7xDmmzpLwPHufzvY_z5ojLuK7svT-pB9Us,8326
21
+ services/query_service.py,sha256=xw5ouFrV8ecg3qODZihVBIbHivKYMeg5pLi2CU1XEbQ,15298
23
22
  services/search_service.py,sha256=bB3FWFxJi1iYsOdBxyu9tzIO406nQxcyeQzEowpmpjY,1803
24
23
  services/sql_service.py,sha256=s84K1ADlvMtum949wgMh8jsmqlOUeL-m_SWfAM4Wsv4,2141
25
24
  services/tasks_service.py,sha256=1DdbERlAxIkCpGEylnHDKC-KAsXRJugbaRSzRbPfL58,6790
26
25
  services/user_feedback_service.py,sha256=_LeNBYz4hHFapXfYTQVfkkD34gE8j2UeKnyOZ8H0nWo,2442
27
26
  services/user_session_context_service.py,sha256=GluNSgqP6W_hFke4oslSnfGnU_b-ph28BHH6jf3EIm0,3797
28
- iatoolkit-0.7.0.dist-info/METADATA,sha256=I_F_F9diQdbMvZ3E_ygMfwpsITxiqqqnXQ1hNzAdOg8,9300
29
- iatoolkit-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
- iatoolkit-0.7.0.dist-info/top_level.txt,sha256=dqlBbmgo9okD9d_WMR9uYzdup7Rxgj26yFF85jRGeu4,19
31
- iatoolkit-0.7.0.dist-info/RECORD,,
27
+ iatoolkit-0.7.1.dist-info/METADATA,sha256=fUzcLZTwz94BL_jmvcK9XUYIkMurSH0qXPqFi6t2aKo,9300
28
+ iatoolkit-0.7.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
+ iatoolkit-0.7.1.dist-info/top_level.txt,sha256=dqlBbmgo9okD9d_WMR9uYzdup7Rxgj26yFF85jRGeu4,19
30
+ iatoolkit-0.7.1.dist-info/RECORD,,
@@ -5,7 +5,6 @@
5
5
 
6
6
  from common.exceptions import IAToolkitException
7
7
  from services.prompt_manager_service import PromptService
8
- from services.api_service import ApiService
9
8
  from repositories.llm_query_repo import LLMQueryRepo
10
9
  from repositories.models import Company, Function
11
10
  from services.excel_service import ExcelService
@@ -24,12 +23,10 @@ class Dispatcher:
24
23
  prompt_service: PromptService,
25
24
  llmquery_repo: LLMQueryRepo,
26
25
  util: Utility,
27
- api_service: ApiService,
28
26
  excel_service: ExcelService,
29
27
  mail_service: MailService):
30
28
  self.prompt_service = prompt_service
31
29
  self.llmquery_repo = llmquery_repo
32
- self.api_service = api_service
33
30
  self.util = util
34
31
  self.excel_service = excel_service
35
32
  self.mail_service = mail_service
@@ -42,7 +39,6 @@ class Dispatcher:
42
39
  self.tool_handlers = {
43
40
  "iat_generate_excel": self.excel_service.excel_generator,
44
41
  "iat_send_email": self.mail_service.send_mail,
45
- "iat_api_call": self.api_service.call_api
46
42
  }
47
43
 
48
44
  @property
@@ -61,13 +57,17 @@ class Dispatcher:
61
57
  return self._company_instances
62
58
 
63
59
  def start_execution(self):
60
+ # initialize the system functions and prompts
61
+ self.setup_iatoolkit_system()
62
+
64
63
  """Runs the startup logic for all registered companies."""
65
- for company_name, company_instance in self.company_instances.items():
66
- company_instance.start_execution()
64
+ for company in self.company_instances.values():
65
+ company.register_company()
66
+ company.start_execution()
67
67
 
68
68
  return True
69
69
 
70
- def setup_all_companies(self):
70
+ def setup_iatoolkit_system(self):
71
71
  # create system functions
72
72
  for function in self.system_functions:
73
73
  self.llmquery_repo.create_or_update_function(
@@ -80,16 +80,16 @@ class Dispatcher:
80
80
  )
81
81
  )
82
82
 
83
- # create the system prompts
84
- i = 1
85
- for prompt in self.system_prompts:
86
- self.prompt_service.create_prompt(
87
- prompt_name=prompt['name'],
88
- description=prompt['description'],
89
- order=1,
90
- is_system_prompt=True,
91
- )
92
- i += 1
83
+ # create the system prompts
84
+ i = 1
85
+ for prompt in self.system_prompts:
86
+ self.prompt_service.create_prompt(
87
+ prompt_name=prompt['name'],
88
+ description=prompt['description'],
89
+ order=1,
90
+ is_system_prompt=True,
91
+ )
92
+ i += 1
93
93
 
94
94
  # register in the database every company class
95
95
  for company in self.company_instances.values():
@@ -120,6 +120,10 @@ class LoadDocumentsService:
120
120
  context (dict, optional): A context dictionary, may contain predefined metadata.
121
121
  """
122
122
 
123
+ if not company:
124
+ raise IAToolkitException(IAToolkitException.ErrorType.MISSING_PARAMETER,
125
+ f"Falta configurar empresa")
126
+
123
127
  # check if file exist in repositories
124
128
  if self.doc_repo.get(company_id=company.id,filename=filename):
125
129
  return
@@ -29,8 +29,7 @@ class PromptService:
29
29
  category: PromptCategory = None,
30
30
  active: bool = True,
31
31
  is_system_prompt: bool = False,
32
- custom_fields: list = [],
33
- params: dict = {}
32
+ custom_fields: list = []
34
33
  ):
35
34
 
36
35
  prompt_filename = prompt_name.lower() + '.prompt'
@@ -46,6 +45,16 @@ class PromptService:
46
45
  raise IAToolkitException(IAToolkitException.ErrorType.INVALID_NAME,
47
46
  f'No existe el archivo de prompt: {relative_prompt_path}')
48
47
 
48
+ if custom_fields:
49
+ for f in custom_fields:
50
+ if ('data_key' not in f) or ('label' not in f):
51
+ raise IAToolkitException(IAToolkitException.ErrorType.INVALID_PARAMETER,
52
+ f'El campo custom_fields debe contener los campos: data_key y label')
53
+
54
+ # add default value for data_type
55
+ if 'type' not in f:
56
+ f['type'] = 'text'
57
+
49
58
  prompt = Prompt(
50
59
  company_id=company.id if company else None,
51
60
  name=prompt_name,
@@ -55,8 +64,7 @@ class PromptService:
55
64
  active=active,
56
65
  filename=prompt_filename,
57
66
  is_system_prompt=is_system_prompt,
58
- custom_fields=custom_fields,
59
- parameters=params
67
+ custom_fields=custom_fields
60
68
  )
61
69
 
62
70
  try:
services/query_service.py CHANGED
@@ -210,14 +210,8 @@ class QueryService:
210
210
  company=company,
211
211
  )
212
212
 
213
- # client profile
214
- client_profile = ''
215
- if final_client_data.get('client_identity'):
216
- client_profile = f"cliente sobre el cual se esta consultando se identifica como ´client_identity´ y tiene el valor: {final_client_data.get('client_identity')}"
217
-
218
-
219
213
  # This is the final user-facing prompt for this specific turn
220
- user_turn_prompt = f"{main_prompt}\n{client_profile}\n{files_context}"
214
+ user_turn_prompt = f"{main_prompt}\n{files_context}"
221
215
  if not prompt_name:
222
216
  user_turn_prompt += f"\n### La pregunta que debes responder es: {question}"
223
217
  else:
services/api_service.py DELETED
@@ -1,75 +0,0 @@
1
- # Copyright (c) 2024 Fernando Libedinsky
2
- # Product: IAToolkit
3
- #
4
- # IAToolkit is open source software.
5
-
6
- from infra.call_service import CallServiceClient
7
- from injector import inject
8
- from common.exceptions import IAToolkitException
9
- import json
10
- from typing import Optional, Dict, Any, Union
11
-
12
- class ApiService:
13
- @inject
14
- def __init__(self, call_service: CallServiceClient):
15
- self.call_service = call_service
16
-
17
- def call_api(
18
- self,
19
- endpoint: str,
20
- method: str,
21
- headers: Optional[Dict[str, str]] = None,
22
- params: Optional[Dict[str, Union[str, int, float, bool]]] = None,
23
- body: Optional[Dict[str, Any]] = None,
24
- files: Optional[Dict[str, Any]] = None,
25
- timeout: Union[int, float, tuple] = 10
26
- ) -> str:
27
- """
28
- Ejecuta una llamada HTTP genérica.
29
-
30
- - endpoint: URL completa
31
- - method: GET | POST | PUT | DELETE (case-insensitive)
32
- - headers: dict opcional de cabeceras
33
- - params: dict opcional de query string
34
- - body: dict opcional para JSON (POST/PUT/DELETE)
35
- - files: dict opcional para multipart/form-data (prioriza POST files)
36
- - timeout: segundos (int/float) o tuple (connect, read)
37
- """
38
- m = (method or "").strip().lower()
39
-
40
- if m == "get":
41
- response, status_code = self.call_service.get(
42
- endpoint, params=params, headers=headers, timeout=timeout
43
- )
44
- elif m == "post":
45
- # Si vienen files → multipart; si no → JSON
46
- if files:
47
- response, status_code = self.call_service.post_files(
48
- endpoint, data=files, params=params, headers=headers, timeout=timeout
49
- )
50
- else:
51
- response, status_code = self.call_service.post(
52
- endpoint=endpoint, json_dict=body, params=params, headers=headers, timeout=timeout
53
- )
54
- elif m == "put":
55
- response, status_code = self.call_service.put(
56
- endpoint, json_dict=body, params=params, headers=headers, timeout=timeout
57
- )
58
- elif m == "delete":
59
- response, status_code = self.call_service.delete(
60
- endpoint, json_dict=body, params=params, headers=headers, timeout=timeout
61
- )
62
- else:
63
- raise IAToolkitException(
64
- IAToolkitException.ErrorType.INVALID_PARAMETER,
65
- f"API error: método '{method}' no soportado"
66
- )
67
-
68
- if status_code < 200 or status_code >= 300:
69
- raise IAToolkitException(
70
- IAToolkitException.ErrorType.CALL_ERROR,
71
- f"API {endpoint} error: {status_code}"
72
- )
73
-
74
- # Normalizamos a string JSON (para que el LLM lo consuma consistente)
75
- return json.dumps(response)