iatoolkit 0.3.9__py3-none-any.whl → 0.107.4__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 (150) hide show
  1. iatoolkit/__init__.py +27 -35
  2. iatoolkit/base_company.py +3 -35
  3. iatoolkit/cli_commands.py +18 -47
  4. iatoolkit/common/__init__.py +0 -0
  5. iatoolkit/common/exceptions.py +48 -0
  6. iatoolkit/common/interfaces/__init__.py +0 -0
  7. iatoolkit/common/interfaces/asset_storage.py +34 -0
  8. iatoolkit/common/interfaces/database_provider.py +39 -0
  9. iatoolkit/common/model_registry.py +159 -0
  10. iatoolkit/common/routes.py +138 -0
  11. iatoolkit/common/session_manager.py +26 -0
  12. iatoolkit/common/util.py +353 -0
  13. iatoolkit/company_registry.py +66 -29
  14. iatoolkit/core.py +514 -0
  15. iatoolkit/infra/__init__.py +5 -0
  16. iatoolkit/infra/brevo_mail_app.py +123 -0
  17. iatoolkit/infra/call_service.py +140 -0
  18. iatoolkit/infra/connectors/__init__.py +5 -0
  19. iatoolkit/infra/connectors/file_connector.py +17 -0
  20. iatoolkit/infra/connectors/file_connector_factory.py +57 -0
  21. iatoolkit/infra/connectors/google_cloud_storage_connector.py +53 -0
  22. iatoolkit/infra/connectors/google_drive_connector.py +68 -0
  23. iatoolkit/infra/connectors/local_file_connector.py +46 -0
  24. iatoolkit/infra/connectors/s3_connector.py +33 -0
  25. iatoolkit/infra/google_chat_app.py +57 -0
  26. iatoolkit/infra/llm_providers/__init__.py +0 -0
  27. iatoolkit/infra/llm_providers/deepseek_adapter.py +278 -0
  28. iatoolkit/infra/llm_providers/gemini_adapter.py +350 -0
  29. iatoolkit/infra/llm_providers/openai_adapter.py +124 -0
  30. iatoolkit/infra/llm_proxy.py +268 -0
  31. iatoolkit/infra/llm_response.py +45 -0
  32. iatoolkit/infra/redis_session_manager.py +122 -0
  33. iatoolkit/locales/en.yaml +222 -0
  34. iatoolkit/locales/es.yaml +225 -0
  35. iatoolkit/repositories/__init__.py +5 -0
  36. iatoolkit/repositories/database_manager.py +187 -0
  37. iatoolkit/repositories/document_repo.py +33 -0
  38. iatoolkit/repositories/filesystem_asset_repository.py +36 -0
  39. iatoolkit/repositories/llm_query_repo.py +105 -0
  40. iatoolkit/repositories/models.py +279 -0
  41. iatoolkit/repositories/profile_repo.py +171 -0
  42. iatoolkit/repositories/vs_repo.py +150 -0
  43. iatoolkit/services/__init__.py +5 -0
  44. iatoolkit/services/auth_service.py +193 -0
  45. {services → iatoolkit/services}/benchmark_service.py +7 -7
  46. iatoolkit/services/branding_service.py +153 -0
  47. iatoolkit/services/company_context_service.py +214 -0
  48. iatoolkit/services/configuration_service.py +375 -0
  49. iatoolkit/services/dispatcher_service.py +134 -0
  50. {services → iatoolkit/services}/document_service.py +20 -8
  51. iatoolkit/services/embedding_service.py +148 -0
  52. iatoolkit/services/excel_service.py +156 -0
  53. {services → iatoolkit/services}/file_processor_service.py +36 -21
  54. iatoolkit/services/history_manager_service.py +208 -0
  55. iatoolkit/services/i18n_service.py +104 -0
  56. iatoolkit/services/jwt_service.py +80 -0
  57. iatoolkit/services/language_service.py +89 -0
  58. iatoolkit/services/license_service.py +82 -0
  59. iatoolkit/services/llm_client_service.py +438 -0
  60. iatoolkit/services/load_documents_service.py +174 -0
  61. iatoolkit/services/mail_service.py +213 -0
  62. {services → iatoolkit/services}/profile_service.py +200 -101
  63. iatoolkit/services/prompt_service.py +303 -0
  64. iatoolkit/services/query_service.py +467 -0
  65. iatoolkit/services/search_service.py +55 -0
  66. iatoolkit/services/sql_service.py +169 -0
  67. iatoolkit/services/tool_service.py +246 -0
  68. iatoolkit/services/user_feedback_service.py +117 -0
  69. iatoolkit/services/user_session_context_service.py +213 -0
  70. iatoolkit/static/images/fernando.jpeg +0 -0
  71. iatoolkit/static/images/iatoolkit_core.png +0 -0
  72. iatoolkit/static/images/iatoolkit_logo.png +0 -0
  73. iatoolkit/static/js/chat_feedback_button.js +80 -0
  74. iatoolkit/static/js/chat_filepond.js +85 -0
  75. iatoolkit/static/js/chat_help_content.js +124 -0
  76. iatoolkit/static/js/chat_history_button.js +110 -0
  77. iatoolkit/static/js/chat_logout_button.js +36 -0
  78. iatoolkit/static/js/chat_main.js +401 -0
  79. iatoolkit/static/js/chat_model_selector.js +227 -0
  80. iatoolkit/static/js/chat_onboarding_button.js +103 -0
  81. iatoolkit/static/js/chat_prompt_manager.js +94 -0
  82. iatoolkit/static/js/chat_reload_button.js +38 -0
  83. iatoolkit/static/styles/chat_iatoolkit.css +559 -0
  84. iatoolkit/static/styles/chat_modal.css +133 -0
  85. iatoolkit/static/styles/chat_public.css +135 -0
  86. iatoolkit/static/styles/documents.css +598 -0
  87. iatoolkit/static/styles/landing_page.css +398 -0
  88. iatoolkit/static/styles/llm_output.css +148 -0
  89. iatoolkit/static/styles/onboarding.css +176 -0
  90. iatoolkit/system_prompts/__init__.py +0 -0
  91. iatoolkit/system_prompts/query_main.prompt +30 -23
  92. iatoolkit/system_prompts/sql_rules.prompt +47 -12
  93. iatoolkit/templates/_company_header.html +45 -0
  94. iatoolkit/templates/_login_widget.html +42 -0
  95. iatoolkit/templates/base.html +78 -0
  96. iatoolkit/templates/change_password.html +66 -0
  97. iatoolkit/templates/chat.html +337 -0
  98. iatoolkit/templates/chat_modals.html +185 -0
  99. iatoolkit/templates/error.html +51 -0
  100. iatoolkit/templates/forgot_password.html +51 -0
  101. iatoolkit/templates/onboarding_shell.html +106 -0
  102. iatoolkit/templates/signup.html +79 -0
  103. iatoolkit/views/__init__.py +5 -0
  104. iatoolkit/views/base_login_view.py +96 -0
  105. iatoolkit/views/change_password_view.py +116 -0
  106. iatoolkit/views/chat_view.py +76 -0
  107. iatoolkit/views/embedding_api_view.py +65 -0
  108. iatoolkit/views/forgot_password_view.py +75 -0
  109. iatoolkit/views/help_content_api_view.py +54 -0
  110. iatoolkit/views/history_api_view.py +56 -0
  111. iatoolkit/views/home_view.py +63 -0
  112. iatoolkit/views/init_context_api_view.py +74 -0
  113. iatoolkit/views/llmquery_api_view.py +59 -0
  114. iatoolkit/views/load_company_configuration_api_view.py +49 -0
  115. iatoolkit/views/load_document_api_view.py +65 -0
  116. iatoolkit/views/login_view.py +170 -0
  117. iatoolkit/views/logout_api_view.py +57 -0
  118. iatoolkit/views/profile_api_view.py +46 -0
  119. iatoolkit/views/prompt_api_view.py +37 -0
  120. iatoolkit/views/root_redirect_view.py +22 -0
  121. iatoolkit/views/signup_view.py +100 -0
  122. iatoolkit/views/static_page_view.py +27 -0
  123. iatoolkit/views/user_feedback_api_view.py +60 -0
  124. iatoolkit/views/users_api_view.py +33 -0
  125. iatoolkit/views/verify_user_view.py +60 -0
  126. iatoolkit-0.107.4.dist-info/METADATA +268 -0
  127. iatoolkit-0.107.4.dist-info/RECORD +132 -0
  128. iatoolkit-0.107.4.dist-info/licenses/LICENSE +21 -0
  129. iatoolkit-0.107.4.dist-info/licenses/LICENSE_COMMUNITY.md +15 -0
  130. {iatoolkit-0.3.9.dist-info → iatoolkit-0.107.4.dist-info}/top_level.txt +0 -1
  131. iatoolkit/iatoolkit.py +0 -413
  132. iatoolkit/system_prompts/arquitectura.prompt +0 -32
  133. iatoolkit-0.3.9.dist-info/METADATA +0 -252
  134. iatoolkit-0.3.9.dist-info/RECORD +0 -32
  135. services/__init__.py +0 -5
  136. services/api_service.py +0 -75
  137. services/dispatcher_service.py +0 -351
  138. services/excel_service.py +0 -98
  139. services/history_service.py +0 -45
  140. services/jwt_service.py +0 -91
  141. services/load_documents_service.py +0 -212
  142. services/mail_service.py +0 -62
  143. services/prompt_manager_service.py +0 -172
  144. services/query_service.py +0 -334
  145. services/search_service.py +0 -32
  146. services/sql_service.py +0 -42
  147. services/tasks_service.py +0 -188
  148. services/user_feedback_service.py +0 -67
  149. services/user_session_context_service.py +0 -85
  150. {iatoolkit-0.3.9.dist-info → iatoolkit-0.107.4.dist-info}/WHEEL +0 -0
@@ -0,0 +1,46 @@
1
+ # iatoolkit/views/profile_api_view.py
2
+ from flask import request, jsonify
3
+ from flask.views import MethodView
4
+ from injector import inject
5
+ from iatoolkit.services.auth_service import AuthService
6
+ from iatoolkit.services.profile_service import ProfileService
7
+
8
+
9
+ class UserLanguageApiView(MethodView):
10
+ """
11
+ API endpoint for managing user language preferences.
12
+ """
13
+
14
+ @inject
15
+ def __init__(self,
16
+ auth_service: AuthService,
17
+ profile_service: ProfileService):
18
+ self.auth_service = auth_service
19
+ self.profile_service = profile_service
20
+
21
+ def post(self):
22
+ """
23
+ Handles POST requests to update the user's preferred language.
24
+ Expects a JSON body with a 'language' key, e.g., {"language": "en"}.
25
+ """
26
+ # 1. Authenticate the user from the current session.
27
+ auth_result = self.auth_service.verify()
28
+ if not auth_result.get("success"):
29
+ return jsonify(auth_result), auth_result.get("status_code")
30
+
31
+ user_identifier = auth_result.get('user_identifier')
32
+
33
+ # 2. Validate request body
34
+ data = request.get_json()
35
+ if not data or 'language' not in data:
36
+ return jsonify({"error_message": "Missing 'language' field in request body"}), 400
37
+
38
+ new_lang = data.get('language')
39
+
40
+ # 3. Call the service to perform the update
41
+ update_result = self.profile_service.update_user_language(user_identifier, new_lang)
42
+
43
+ if not update_result.get('success'):
44
+ return jsonify(update_result), 400
45
+
46
+ return jsonify({"message": "Language preference updated successfully"}), 200
@@ -0,0 +1,37 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from flask import jsonify
7
+ from flask.views import MethodView
8
+ from iatoolkit.services.prompt_service import PromptService
9
+ from iatoolkit.services.auth_service import AuthService
10
+ from injector import inject
11
+ import logging
12
+
13
+
14
+ class PromptApiView(MethodView):
15
+ @inject
16
+ def __init__(self,
17
+ auth_service: AuthService,
18
+ prompt_service: PromptService ):
19
+ self.auth_service = auth_service
20
+ self.prompt_service = prompt_service
21
+
22
+ def get(self, company_short_name):
23
+ try:
24
+ # get access credentials
25
+ auth_result = self.auth_service.verify(anonymous=True)
26
+ if not auth_result.get("success"):
27
+ return jsonify(auth_result), auth_result.get('status_code')
28
+
29
+ response = self.prompt_service.get_user_prompts(company_short_name)
30
+ if "error" in response:
31
+ return {'error_message': response["error"]}, 402
32
+
33
+ return response, 200
34
+ except Exception as e:
35
+ logging.exception(
36
+ f"unexpected error getting company prompts: {e}")
37
+ return jsonify({"error_message": str(e)}), 500
@@ -0,0 +1,22 @@
1
+ from flask import redirect, url_for
2
+ from flask.views import MethodView
3
+ from iatoolkit.company_registry import get_company_registry
4
+
5
+
6
+ class RootRedirectView(MethodView):
7
+ """
8
+ Vista que redirige la raíz '/' al home de la primera compañía disponible.
9
+ """
10
+
11
+ def get(self):
12
+ registry = get_company_registry()
13
+ companies = registry.get_all_company_instances()
14
+
15
+ if companies:
16
+ # Obtener el short_name de la primera compañía registrada.
17
+ # En Python 3.7+, los diccionarios mantienen el orden de inserción.
18
+ first_company_short_name = next(iter(companies))
19
+ return redirect(url_for('home', company_short_name=first_company_short_name))
20
+
21
+ # Fallback: Si no hay compañías, ir al index genérico (o a un 404)
22
+ return redirect(url_for('index'))
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from flask.views import MethodView
7
+ from flask import render_template, request, url_for, redirect, flash
8
+ from iatoolkit.services.profile_service import ProfileService
9
+ from iatoolkit.services.branding_service import BrandingService
10
+ from iatoolkit.services.i18n_service import I18nService
11
+ from injector import inject
12
+ from itsdangerous import URLSafeTimedSerializer
13
+ import os
14
+
15
+
16
+ class SignupView(MethodView):
17
+ @inject
18
+ def __init__(self, profile_service: ProfileService,
19
+ branding_service: BrandingService,
20
+ i18n_service: I18nService):
21
+ self.profile_service = profile_service
22
+ self.branding_service = branding_service # 3. Guardar la instancia
23
+ self.i18n_service = i18n_service
24
+
25
+ self.serializer = URLSafeTimedSerializer(os.getenv("IATOOLKIT_SECRET_KEY"))
26
+
27
+
28
+ def get(self, company_short_name: str):
29
+ # get company info
30
+ company = self.profile_service.get_company_by_short_name(company_short_name)
31
+ if not company:
32
+ return render_template('error.html',
33
+ message=self.i18n_service.t('errors.templates.company_not_found')), 404
34
+
35
+ branding_data = self.branding_service.get_company_branding(company_short_name)
36
+ current_lang = request.args.get("lang") or "en"
37
+
38
+ return render_template('signup.html',
39
+ company_short_name=company_short_name,
40
+ branding=branding_data,
41
+ lang=current_lang)
42
+
43
+ def post(self, company_short_name: str):
44
+ try:
45
+ company = self.profile_service.get_company_by_short_name(company_short_name)
46
+ if not company:
47
+ return render_template('error.html',
48
+ message=self.i18n_service.t('errors.templates.company_not_found')), 404
49
+
50
+ branding_data = self.branding_service.get_company_branding(company_short_name)
51
+
52
+ first_name = request.form.get('first_name')
53
+ last_name = request.form.get('last_name')
54
+ email = request.form.get('email')
55
+ password = request.form.get('password')
56
+ confirm_password = request.form.get('confirm_password')
57
+
58
+ # get the language from the form, then query
59
+ current_lang = request.form.get("lang") or request.args.get("lang")
60
+
61
+ # create verification token and url for verification
62
+ token = self.serializer.dumps(email, salt='email-confirm')
63
+ verification_url = url_for('verify_account',
64
+ company_short_name=company_short_name,
65
+ token=token, _external=True)
66
+
67
+ response = self.profile_service.signup(
68
+ company_short_name=company_short_name,
69
+ email=email,
70
+ first_name=first_name, last_name=last_name,
71
+ password=password, confirm_password=confirm_password,
72
+ verification_url=verification_url)
73
+
74
+ if "error" in response:
75
+ flash(response["error"], 'error')
76
+ return render_template(
77
+ 'signup.html',
78
+ company_short_name=company_short_name,
79
+ branding=branding_data,
80
+ lang=current_lang,
81
+ form_data={
82
+ "first_name": first_name,
83
+ "last_name": last_name,
84
+ "email": email,
85
+ "password": password,
86
+ "confirm_password": confirm_password
87
+ }), 400
88
+
89
+ flash(response["message"], 'success')
90
+ return redirect(url_for('home', company_short_name=company_short_name, lang=current_lang))
91
+
92
+ except Exception as e:
93
+ message = self.i18n_service.t('errors.templates.processing_error', error=str(e))
94
+ return render_template(
95
+ "error.html",
96
+ company_short_name=company_short_name,
97
+ branding=branding_data,
98
+ message=message,
99
+ lang=current_lang
100
+ ), 500
@@ -0,0 +1,27 @@
1
+ from flask import render_template
2
+ from flask.views import MethodView
3
+ from injector import inject
4
+
5
+
6
+ class StaticPageView(MethodView):
7
+ """
8
+ View genérica para servir páginas estáticas simples (sin lógica de negocio compleja).
9
+ """
10
+
11
+ @inject
12
+ def __init__(self):
13
+ pass
14
+
15
+ def get(self, page_name: str):
16
+ # Mapeo seguro de nombres de página a plantillas
17
+ # Esto evita que se intente cargar cualquier archivo arbitrario
18
+ valid_pages = {
19
+ 'foundation': 'docs/foundation.html',
20
+ 'mini_project': 'docs/mini_project.html'
21
+ }
22
+
23
+ if page_name not in valid_pages:
24
+ # Si la página no existe, podríamos retornar un 404 o redirigir al index
25
+ return render_template('error.html', message=f"Página no encontrada: {page_name}"), 404
26
+
27
+ return render_template(valid_pages[page_name])
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from flask import request, jsonify
7
+ from flask.views import MethodView
8
+ from iatoolkit.services.user_feedback_service import UserFeedbackService
9
+ from iatoolkit.services.auth_service import AuthService
10
+ from injector import inject
11
+ import logging
12
+
13
+
14
+ class UserFeedbackApiView(MethodView):
15
+ @inject
16
+ def __init__(self,
17
+ auth_service: AuthService,
18
+ user_feedback_service: UserFeedbackService ):
19
+ self.auth_service = auth_service
20
+ self.user_feedback_service = user_feedback_service
21
+
22
+ def post(self, company_short_name):
23
+ try:
24
+ # get access credentials
25
+ auth_result = self.auth_service.verify()
26
+ if not auth_result.get("success"):
27
+ return jsonify(auth_result), auth_result.get("status_code")
28
+
29
+ user_identifier = auth_result.get('user_identifier')
30
+
31
+ data = request.get_json()
32
+ if not data:
33
+ return jsonify({"error_message": "invalid json body"}), 402
34
+
35
+ # these validations are performed also in the frontend
36
+ # the are localized in the front
37
+ message = data.get("message")
38
+ if not message:
39
+ return jsonify({"error_message": "missing feedback message"}), 400
40
+
41
+ rating = data.get("rating")
42
+ if not rating:
43
+ return jsonify({"error_message": "missing rating"}), 400
44
+
45
+ response = self.user_feedback_service.new_feedback(
46
+ company_short_name=company_short_name,
47
+ message=message,
48
+ user_identifier=user_identifier,
49
+ rating=rating
50
+ )
51
+
52
+ if "error" in response:
53
+ return {'error_message': response["error"]}, 402
54
+
55
+ return response, 200
56
+ except Exception as e:
57
+ logging.exception(
58
+ f"unexpected error processing feedback for {company_short_name}: {e}")
59
+ return jsonify({"error_message": str(e)}), 500
60
+
@@ -0,0 +1,33 @@
1
+ from flask.views import MethodView
2
+ from flask import jsonify
3
+ from injector import inject
4
+ from iatoolkit.services.auth_service import AuthService
5
+ from iatoolkit.services.profile_service import ProfileService
6
+ import logging
7
+
8
+
9
+ class UsersApiView(MethodView):
10
+ """
11
+ list company users and their roles
12
+ """
13
+ @inject
14
+ def __init__(self,
15
+ auth_service: AuthService,
16
+ profile_service: ProfileService):
17
+ self.auth_service = auth_service
18
+ self.profile_service = profile_service
19
+
20
+ def get(self, company_short_name: str):
21
+ try:
22
+ auth_result = self.auth_service.verify(anonymous=True)
23
+ if not auth_result.get("success"):
24
+ return jsonify(auth_result), auth_result.get("status_code", 401)
25
+
26
+ # get users of the company
27
+ users = self.profile_service.get_company_users(company_short_name)
28
+
29
+ return jsonify(users), 200
30
+
31
+ except Exception as e:
32
+ logging.exception(f"Error fetching users for {company_short_name}: {e}")
33
+ return jsonify({"error": "Unexpected error", "details": str(e)}), 500
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from flask.views import MethodView
7
+ from flask import render_template, url_for, redirect, session, flash
8
+ from iatoolkit.services.profile_service import ProfileService
9
+ from itsdangerous import URLSafeTimedSerializer, SignatureExpired
10
+ from iatoolkit.services.branding_service import BrandingService
11
+ from iatoolkit.services.i18n_service import I18nService
12
+ from injector import inject
13
+ import os
14
+
15
+
16
+ class VerifyAccountView(MethodView):
17
+ @inject
18
+ def __init__(self,
19
+ profile_service: ProfileService,
20
+ branding_service: BrandingService,
21
+ i18n_service: I18nService):
22
+ self.profile_service = profile_service
23
+ self.branding_service = branding_service
24
+ self.i18n_service = i18n_service
25
+ self.serializer = URLSafeTimedSerializer(os.getenv("IATOOLKIT_SECRET_KEY"))
26
+
27
+ def get(self, company_short_name: str, token: str):
28
+ try:
29
+ # get company info
30
+ company = self.profile_service.get_company_by_short_name(company_short_name)
31
+ if not company:
32
+ return render_template('error.html',
33
+ message=self.i18n_service.t('errors.templates.company_not_found')), 404
34
+
35
+ branding_data = self.branding_service.get_company_branding(company_short_name)
36
+ try:
37
+ # decode the token from the URL
38
+ email = self.serializer.loads(token, salt='email-confirm', max_age=3600*5)
39
+ except SignatureExpired:
40
+ flash(self.i18n_service.t('errors.verification.token_expired'), 'error')
41
+ return render_template('signup.html',
42
+ company_short_name=company_short_name,
43
+ branding=branding_data,
44
+ token=token), 400
45
+
46
+ response = self.profile_service.verify_account(email)
47
+ if "error" in response:
48
+ flash(response["error"], 'error')
49
+ return render_template(
50
+ 'signup.html',
51
+ company_short_name=company_short_name,
52
+ branding=branding_data,
53
+ token=token), 400
54
+
55
+ flash(response['message'], 'success')
56
+ return redirect(url_for('home', company_short_name=company_short_name))
57
+
58
+ except Exception as e:
59
+ flash(self.i18n_service.t('errors.general.unexpected_error', error=str(e)), 'error')
60
+ return redirect(url_for('home', company_short_name=company_short_name))
@@ -0,0 +1,268 @@
1
+ Metadata-Version: 2.4
2
+ Name: iatoolkit
3
+ Version: 0.107.4
4
+ Summary: IAToolkit
5
+ Author: Fernando Libedinsky
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ License-File: LICENSE_COMMUNITY.md
11
+ Requires-Dist: bcrypt==4.2.1
12
+ Requires-Dist: boto3==1.36.22
13
+ Requires-Dist: botocore==1.36.22
14
+ Requires-Dist: build==1.2.2.post1
15
+ Requires-Dist: click==8.1.8
16
+ Requires-Dist: cryptography==44.0.3
17
+ Requires-Dist: Flask==3.1.0
18
+ Requires-Dist: Flask-Bcrypt==1.0.1
19
+ Requires-Dist: flask-cors==6.0.0
20
+ Requires-Dist: Flask-Injector==0.15.0
21
+ Requires-Dist: Flask-Session==0.8.0
22
+ Requires-Dist: flatbuffers==24.3.25
23
+ Requires-Dist: google-ai-generativelanguage==0.6.15
24
+ Requires-Dist: google-api-core==2.24.1
25
+ Requires-Dist: google-api-python-client==2.161.0
26
+ Requires-Dist: google-auth==2.37.0
27
+ Requires-Dist: google-auth-httplib2==0.2.0
28
+ Requires-Dist: google-auth-oauthlib==1.2.1
29
+ Requires-Dist: google-cloud-core==2.4.1
30
+ Requires-Dist: google-cloud-storage==3.0.0
31
+ Requires-Dist: google-crc32c==1.6.0
32
+ Requires-Dist: google-generativeai==0.8.5
33
+ Requires-Dist: google-resumable-media==2.7.2
34
+ Requires-Dist: googleapis-common-protos==1.66.0
35
+ Requires-Dist: gunicorn==23.0.0
36
+ Requires-Dist: h11==0.14.0
37
+ Requires-Dist: httpcore==1.0.7
38
+ Requires-Dist: httplib2==0.22.0
39
+ Requires-Dist: httptools==0.6.4
40
+ Requires-Dist: httpx==0.28.0
41
+ Requires-Dist: httpx-sse==0.4.0
42
+ Requires-Dist: huggingface-hub==0.31.4
43
+ Requires-Dist: humanfriendly==10.0
44
+ Requires-Dist: idna==3.10
45
+ Requires-Dist: injector==0.22.0
46
+ Requires-Dist: Jinja2==3.1.5
47
+ Requires-Dist: langchain==0.3.19
48
+ Requires-Dist: langchain-core==0.3.35
49
+ Requires-Dist: langchain-text-splitters==0.3.6
50
+ Requires-Dist: markdown2==2.5.3
51
+ Requires-Dist: openai==2.8.1
52
+ Requires-Dist: openpyxl==3.1.5
53
+ Requires-Dist: pandas==2.3.1
54
+ Requires-Dist: pgvector==0.3.6
55
+ Requires-Dist: pillow==11.0.0
56
+ Requires-Dist: psutil==7.0.0
57
+ Requires-Dist: psycopg2-binary==2.9.10
58
+ Requires-Dist: PyJWT==2.10.1
59
+ Requires-Dist: PyMuPDF==1.25.0
60
+ Requires-Dist: python-dotenv==1.0.1
61
+ Requires-Dist: pytest==8.3.4
62
+ Requires-Dist: pytest-cov==5.0.0
63
+ Requires-Dist: pytest-mock==3.14.0
64
+ Requires-Dist: python-dateutil==2.9.0.post0
65
+ Requires-Dist: python-docx==1.1.2
66
+ Requires-Dist: pytesseract==0.3.13
67
+ Requires-Dist: pytz==2025.2
68
+ Requires-Dist: PyYAML==6.0.2
69
+ Requires-Dist: redis==5.2.1
70
+ Requires-Dist: regex==2024.11.6
71
+ Requires-Dist: requests==2.32.3
72
+ Requires-Dist: requests-oauthlib==2.0.0
73
+ Requires-Dist: requests-toolbelt==1.0.0
74
+ Requires-Dist: s3transfer==0.11.2
75
+ Requires-Dist: sib-api-v3-sdk==7.6.0
76
+ Requires-Dist: SQLAlchemy==2.0.36
77
+ Requires-Dist: tiktoken==0.8.0
78
+ Requires-Dist: tokenizers==0.21.0
79
+ Requires-Dist: websocket-client==1.8.0
80
+ Requires-Dist: websockets==14.1
81
+ Requires-Dist: Werkzeug==3.1.3
82
+ Requires-Dist: pyjwt[crypto]>=2.8.0
83
+ Dynamic: license-file
84
+
85
+ # 🧠 IAToolkit — Open-Source Framework for Real-World AI Assistants
86
+
87
+ Build private, production-grade AI assistants that run entirely inside your environment and speak the language of your business.
88
+
89
+ IAToolkit is not a demo wrapper or a prompt playground — it is a **full architecture** for implementing intelligent systems that combine LLMs, SQL data, internal documents, tools, workflows, and multi-tenant business logic.
90
+
91
+ ---
92
+
93
+ ## 🚀 Why IAToolkit?
94
+
95
+ Modern AI development is fragmented: LangChain handles chains, LlamaIndex handles documents,
96
+ your backend handles SQL, your frontend handles chats, and your devs glue everything together.
97
+
98
+ **IAToolkit brings all of this into one unified, production-ready framework.**
99
+
100
+ It focuses on:
101
+
102
+ - **real-world data** (SQL + documents)
103
+ - **real workflows** (LLM tools + python services)
104
+ - **real multi-tenant architecture** (1 company → many companies)
105
+ - **real constraints** (security, reproducibility, governance)
106
+ - **real deployment** (your servers, your infrastructure)
107
+
108
+ IAToolkit lets you build the assistant that *your* organization needs — not a generic chatbot.
109
+
110
+ ---
111
+
112
+ ## 🧩 Architecture in a Nutshell
113
+
114
+ IAToolkit is a structured, layered framework:
115
+
116
+ Interfaces (Web & API)
117
+
118
+ Intelligence Layer (prompts, tools, SQL orchestration, RAG)
119
+
120
+ Execution Layer (services, workflows, validation)
121
+
122
+ Data Access (SQLAlchemy, connectors)
123
+
124
+ Company Modules (company.yaml + custom tools)
125
+
126
+ ### ✔ Interfaces
127
+ Chat UI, REST API, auth, sessions, JSON/HTML responses.
128
+
129
+ ### ✔ Intelligence Layer
130
+ Core logic: prompt rendering, SQL orchestration, RAG, LLM tool dispatching.
131
+
132
+ ### ✔ Execution Layer
133
+ Python services that implement real workflows: querying data, generating reports, retrieving documents, executing business logic.
134
+
135
+ ### ✔ Data Access
136
+ A clean repository pattern using SQLAlchemy.
137
+
138
+ ### ✔ Company Modules
139
+ Each company has:
140
+
141
+ - its own `company.yaml`
142
+ - its own prompts
143
+ - its own tools
144
+ - its own services
145
+ - its own vector store & SQL context
146
+
147
+ This modularity allows **true multi-tenancy**.
148
+
149
+ ---
150
+
151
+ ## 🔌 Connect to Anything
152
+
153
+ IAToolkit integrates naturally with:
154
+
155
+ - **SQL databases** (PostgreSQL, MySQL, SQL Server, etc.)
156
+ - **Document retrieval** (PDF, text, embeddings)
157
+ - **External APIs**
158
+ - **Internal microservices**
159
+ - **Custom Python tools**
160
+
161
+ It also includes a **production-grade RAG pipeline**, combining:
162
+
163
+ - embeddings
164
+ - chunking
165
+ - hybrid search
166
+ - SQL queries + document retrieval
167
+ - tool execution
168
+
169
+ Everything orchestrated through the Intelligence Layer.
170
+
171
+ ---
172
+
173
+ ## 🏢 Multi-Tenant Architecture
174
+
175
+ A single installation of IAToolkit can power assistants for multiple companies, departments, or customers.
176
+ ```text
177
+ companies/
178
+ company_a
179
+ company_b
180
+ company_c
181
+ ```
182
+ Each Company is fully isolated:
183
+
184
+ - prompts
185
+ - tools
186
+ - credentials
187
+ - documents
188
+ - SQL contexts
189
+ - business rules
190
+
191
+ This makes IAToolkit ideal for SaaS products, agencies, consultancies, and organizations with multiple business units.
192
+
193
+ ---
194
+
195
+ ## 🆓 Community Edition vs Enterprise Edition
196
+
197
+ IAToolkit follows a modern **open-core** model:
198
+
199
+ ### 🟦 Community Edition (MIT License)
200
+ - Full Open-Source Core
201
+ - SQL + Basic RAG
202
+ - One Company
203
+ - Custom Python tools
204
+ - Self-managed deployment
205
+
206
+ Perfect for developers, small teams, single-business use cases, and experimentation.
207
+
208
+ ### 🟥 Enterprise Edition (Commercial License)
209
+ - Unlimited Companies (multi-tenant)
210
+ - Payment services integration
211
+ - Enterprise Agent Workflows
212
+ - SSO integration
213
+ - Priority support & continuous updates
214
+ - Activation via **License Key**
215
+
216
+ 👉 Licensing information:
217
+ - [Community Edition (MIT)](LICENSE_COMMUNITY.md)
218
+ - [Enterprise License](ENTERPRISE_LICENSE.md)
219
+
220
+ ---
221
+
222
+ ## 🧩 Who Is IAToolkit For?
223
+
224
+ - Companies building internal “ChatGPT for the business”
225
+ - SaaS products adding AI assistants for multiple customers
226
+ - AI teams that need reproducible prompts and controlled tools
227
+ - Developers who want real workflows, not toy demos
228
+ - Organizations requiring privacy, security, and self-hosting
229
+ - Teams working with SQL-heavy business logic
230
+ - Consultancies deploying AI for multiple clients
231
+
232
+ ---
233
+
234
+ ## ⭐ Key Differentiators
235
+
236
+ - prioritizes **architecture-first design**, not chains or wrappers
237
+ - supports **multi-company** out of the box
238
+ - integrates **SQL, RAG, and tools** into a single intelligence layer
239
+ - keeps **business logic isolated** inside Company modules
240
+ - runs entirely **on your own infrastructure**
241
+ - ships with a **full web chat**, and API.
242
+ - is built for **production**, not prototypes
243
+
244
+ ---
245
+
246
+ ## 📚 Documentation
247
+
248
+ - 🚀 **[Quickstart](docs/quickstart.md)** – Set up your environment and run the project
249
+ - ☁️ **[Deployment Guide](docs/deployment_guide.md)** – Production deployment instructions
250
+ - 🏗️ **[Companies & Components](docs/companies_and_components.md)** – how Company modules work
251
+ - 🧠 **[Programming Guide](docs/programming_guide.md)** – services, intelligence layer, dispatching
252
+ - 🗃️ **[Database Guide](docs/database_guide.md)** – internal schema overview
253
+ - 🌱 **[Foundation Article](https://iatoolkit.com/pages/foundation)** – the “Why” behind the architecture
254
+ - 📘 **[Mini-Project (3 months)](https://iatoolkit.com/pages/mini_project)** – how to deploy a corporate AI assistant
255
+
256
+
257
+ ---
258
+
259
+ ## 🤝 Contributing
260
+
261
+ IAToolkit is open-source and community-friendly.
262
+ PRs, issues, ideas, and feedback are always welcome.
263
+
264
+ ---
265
+
266
+ ## ⭐ Support the Project
267
+
268
+ If you find IAToolkit useful, please **star the GitHub repo** — it helps visibility and adoption.