iatoolkit 0.66.7__tar.gz → 0.69.0__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.69.0/LICENSE +21 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/PKG-INFO +40 -22
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/pyproject.toml +1 -1
- iatoolkit-0.69.0/readme.md +65 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/__init__.py +0 -2
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/base_company.py +1 -26
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/company_registry.py +1 -2
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/iatoolkit.py +5 -4
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/database_manager.py +5 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/models.py +0 -5
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/profile_repo.py +0 -4
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/branding_service.py +10 -5
- iatoolkit-0.69.0/src/iatoolkit/services/company_context_service.py +145 -0
- iatoolkit-0.69.0/src/iatoolkit/services/configuration_service.py +133 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/dispatcher_service.py +44 -40
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/language_service.py +9 -5
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/profile_service.py +3 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/query_service.py +4 -1
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/search_service.py +11 -4
- iatoolkit-0.69.0/src/iatoolkit/services/sql_service.py +90 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_onboarding_button.js +6 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +8 -8
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/styles/onboarding.css +7 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/change_password.html +1 -1
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/chat.html +10 -2
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/chat_modals.html +1 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/login_simulation.html +1 -1
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/onboarding_shell.html +4 -1
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/base_login_view.py +7 -8
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/change_password_view.py +2 -3
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/external_login_view.py +1 -1
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/forgot_password_view.py +2 -4
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/help_content_api_view.py +8 -8
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/home_view.py +1 -2
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/login_simulation_view.py +1 -1
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/login_view.py +8 -8
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/signup_view.py +2 -4
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/verify_user_view.py +1 -3
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit.egg-info/PKG-INFO +40 -22
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit.egg-info/SOURCES.txt +3 -2
- iatoolkit-0.66.7/readme.md +0 -49
- iatoolkit-0.66.7/src/iatoolkit/services/help_content_service.py +0 -30
- iatoolkit-0.66.7/src/iatoolkit/services/onboarding_service.py +0 -43
- iatoolkit-0.66.7/src/iatoolkit/services/sql_service.py +0 -64
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/requirements.txt +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/setup.cfg +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/cli_commands.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/common/__init__.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/common/exceptions.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/common/routes.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/common/session_manager.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/common/util.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/__init__.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/call_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/gemini_adapter.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/llm_client.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/llm_response.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/mail_app.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/openai_adapter.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/locales/en.yaml +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/locales/es.yaml +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/__init__.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/document_repo.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/tasks_repo.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/__init__.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/auth_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/benchmark_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/document_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/excel_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/file_processor_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/history_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/i18n_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/jwt_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/load_documents_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/mail_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/prompt_manager_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/tasks_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/images/fernando.jpeg +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_help_content.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_history_button.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_main.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/styles/chat_public.css +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/styles/landing_page.css +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/_company_header.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/_login_widget.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/about.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/base.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/error.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/forgot_password.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/index.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/templates/signup.html +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/__init__.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/file_store_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/history_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/index_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/init_context_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/llmquery_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/logout_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/profile_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/prompt_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/tasks_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/tasks_review_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-0.66.7 → iatoolkit-0.69.0}/src/iatoolkit.egg-info/top_level.txt +0 -0
iatoolkit-0.69.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Fernando Libedinsky
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iatoolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.69.0
|
|
4
4
|
Summary: IAToolkit
|
|
5
5
|
Author: Fernando Libedinsky
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Requires-Python: >=3.12
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
9
10
|
Requires-Dist: aiohappyeyeballs==2.4.4
|
|
10
11
|
Requires-Dist: aiohttp==3.11.9
|
|
11
12
|
Requires-Dist: aiosignal==1.3.1
|
|
@@ -206,47 +207,64 @@ Requires-Dist: wrapt==1.17.0
|
|
|
206
207
|
Requires-Dist: yarl==1.18.3
|
|
207
208
|
Requires-Dist: zipp==3.21.0
|
|
208
209
|
Requires-Dist: zstandard==0.23.0
|
|
210
|
+
Dynamic: license-file
|
|
209
211
|
|
|
210
212
|
|
|
211
213
|
<div align="center">
|
|
212
|
-
|
|
214
|
+
<h1>
|
|
215
|
+
IAToolkit
|
|
216
|
+
</h1>
|
|
217
|
+
|
|
213
218
|
<p><strong>The Open-Source Framework for Building AI Chatbots on Your Private Data.</strong></p>
|
|
219
|
+
<h4>
|
|
220
|
+
<a href="https://www.iatoolkit.com" target="_blank" style="text-decoration: none; color: inherit;">
|
|
221
|
+
www.iatoolkit.com
|
|
222
|
+
</a>
|
|
223
|
+
</h4>
|
|
214
224
|
</div>
|
|
215
225
|
|
|
216
|
-
IAToolkit is a comprehensive, open-source framework designed for building enterprise-grade
|
|
217
|
-
AI chatbots and conversational applications.
|
|
226
|
+
IAToolkit is a comprehensive, Python open-source framework designed for building enterprise-grade
|
|
227
|
+
AI chatbots and conversational applications. It bridges the gap between the power of
|
|
228
|
+
Large Language Models (LLMs) and the valuable,
|
|
229
|
+
private data locked within your organization's databases and documents.
|
|
230
|
+
|
|
218
231
|
With IAToolkit, you can build production-ready, context-aware chatbots and agents that
|
|
219
232
|
can query relational databases, perform semantic searches on documents,
|
|
220
233
|
and connect to your internal APIs in minutes.
|
|
221
234
|
|
|
222
|
-
|
|
235
|
+
Create secure, branded chat interfaces that can reason over your data, answer questions, and execute custom business logic,
|
|
236
|
+
all powered by leading models from OpenAI, Google Gemini, and more.
|
|
223
237
|
|
|
224
238
|
|
|
225
239
|
## 🚀 Key Features
|
|
226
240
|
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
241
|
+
* **🔗 Unified Data Connection**
|
|
242
|
+
* **Natural Language to SQL**: Let your chatbot query relational databases (PostgreSQL, MySQL, SQLite) using everyday language.
|
|
243
|
+
* **Semantic Document Search**: Automatically chunk, embed, and search across your private documents (PDFs, Word, etc.) to provide contextually accurate answers.
|
|
230
244
|
|
|
231
|
-
*
|
|
232
|
-
*
|
|
245
|
+
* **🏢 Enterprise-Ready Multi-Tenancy**
|
|
246
|
+
* Deploy isolated "Company" modules, each with its own data, tools, and context.
|
|
247
|
+
* Perfect for SaaS products or internal departmental agents.
|
|
233
248
|
|
|
234
|
-
*
|
|
235
|
-
*
|
|
249
|
+
* **🎨 Fully Brandable UI**
|
|
250
|
+
* Customize the look and feel for each "Company" with its own logos, colors, and even language settings (i18n).
|
|
251
|
+
* Provides a white-labeled experience for your users.
|
|
236
252
|
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* Powerful Flask-based **CLI** for database setup, API key generation, and more.
|
|
253
|
+
* **🧠 LLM Agnostic**
|
|
254
|
+
* Switch between **OpenAI (GPT-*)** and **Google (Gemini-*)** with a single line change in your configuration.
|
|
255
|
+
* No code refactoring needed.
|
|
241
256
|
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
257
|
+
* **🛠️ Developer-First Experience**
|
|
258
|
+
* Built with a clean **Dependency Injection** architecture.
|
|
259
|
+
* High-quality code base with **90%+ test coverage**.
|
|
245
260
|
|
|
246
|
-
|
|
261
|
+
* **🔒 Security & Observability Built-In**
|
|
262
|
+
* Comes with integrated user authentication, API keys, and secure session handling out of the box.
|
|
263
|
+
* Full traceability with detailed logging of all queries, function calls, token usage, and costs.
|
|
264
|
+
## ⚡ Quick Start: Try our 'hello world' example
|
|
247
265
|
|
|
248
|
-
|
|
249
|
-
|
|
266
|
+
Ready to see it in action? Our Quickstart Guide will walk you through downloading, configuring, and launching your first AI assistant in just a few minutes.
|
|
267
|
+
It's the best way to experience the toolkit's capabilities firsthand.
|
|
250
268
|
|
|
251
269
|
## 🤝 Contributing
|
|
252
270
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
|
|
2
|
+
<div align="center">
|
|
3
|
+
<h1>
|
|
4
|
+
IAToolkit
|
|
5
|
+
</h1>
|
|
6
|
+
|
|
7
|
+
<p><strong>The Open-Source Framework for Building AI Chatbots on Your Private Data.</strong></p>
|
|
8
|
+
<h4>
|
|
9
|
+
<a href="https://www.iatoolkit.com" target="_blank" style="text-decoration: none; color: inherit;">
|
|
10
|
+
www.iatoolkit.com
|
|
11
|
+
</a>
|
|
12
|
+
</h4>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
IAToolkit is a comprehensive, Python open-source framework designed for building enterprise-grade
|
|
16
|
+
AI chatbots and conversational applications. It bridges the gap between the power of
|
|
17
|
+
Large Language Models (LLMs) and the valuable,
|
|
18
|
+
private data locked within your organization's databases and documents.
|
|
19
|
+
|
|
20
|
+
With IAToolkit, you can build production-ready, context-aware chatbots and agents that
|
|
21
|
+
can query relational databases, perform semantic searches on documents,
|
|
22
|
+
and connect to your internal APIs in minutes.
|
|
23
|
+
|
|
24
|
+
Create secure, branded chat interfaces that can reason over your data, answer questions, and execute custom business logic,
|
|
25
|
+
all powered by leading models from OpenAI, Google Gemini, and more.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## 🚀 Key Features
|
|
29
|
+
|
|
30
|
+
* **🔗 Unified Data Connection**
|
|
31
|
+
* **Natural Language to SQL**: Let your chatbot query relational databases (PostgreSQL, MySQL, SQLite) using everyday language.
|
|
32
|
+
* **Semantic Document Search**: Automatically chunk, embed, and search across your private documents (PDFs, Word, etc.) to provide contextually accurate answers.
|
|
33
|
+
|
|
34
|
+
* **🏢 Enterprise-Ready Multi-Tenancy**
|
|
35
|
+
* Deploy isolated "Company" modules, each with its own data, tools, and context.
|
|
36
|
+
* Perfect for SaaS products or internal departmental agents.
|
|
37
|
+
|
|
38
|
+
* **🎨 Fully Brandable UI**
|
|
39
|
+
* Customize the look and feel for each "Company" with its own logos, colors, and even language settings (i18n).
|
|
40
|
+
* Provides a white-labeled experience for your users.
|
|
41
|
+
|
|
42
|
+
* **🧠 LLM Agnostic**
|
|
43
|
+
* Switch between **OpenAI (GPT-*)** and **Google (Gemini-*)** with a single line change in your configuration.
|
|
44
|
+
* No code refactoring needed.
|
|
45
|
+
|
|
46
|
+
* **🛠️ Developer-First Experience**
|
|
47
|
+
* Built with a clean **Dependency Injection** architecture.
|
|
48
|
+
* High-quality code base with **90%+ test coverage**.
|
|
49
|
+
|
|
50
|
+
* **🔒 Security & Observability Built-In**
|
|
51
|
+
* Comes with integrated user authentication, API keys, and secure session handling out of the box.
|
|
52
|
+
* Full traceability with detailed logging of all queries, function calls, token usage, and costs.
|
|
53
|
+
## ⚡ Quick Start: Try our 'hello world' example
|
|
54
|
+
|
|
55
|
+
Ready to see it in action? Our Quickstart Guide will walk you through downloading, configuring, and launching your first AI assistant in just a few minutes.
|
|
56
|
+
It's the best way to experience the toolkit's capabilities firsthand.
|
|
57
|
+
|
|
58
|
+
## 🤝 Contributing
|
|
59
|
+
|
|
60
|
+
We welcome contributions! Whether it's adding a new feature, improving documentation, or fixing a bug,
|
|
61
|
+
please feel free to open a pull request.
|
|
62
|
+
|
|
63
|
+
## 📄 License
|
|
64
|
+
|
|
65
|
+
IAToolkit is open-source and licensed under the [MIT License](LICENSE).
|
|
@@ -10,7 +10,6 @@ from .iatoolkit import IAToolkit, current_iatoolkit, create_app
|
|
|
10
10
|
# for registering the client companies
|
|
11
11
|
from .company_registry import register_company
|
|
12
12
|
from .base_company import BaseCompany
|
|
13
|
-
from iatoolkit.repositories.database_manager import DatabaseManager
|
|
14
13
|
|
|
15
14
|
# --- Services ---
|
|
16
15
|
from iatoolkit.services.query_service import QueryService
|
|
@@ -27,7 +26,6 @@ __all__ = [
|
|
|
27
26
|
'current_iatoolkit',
|
|
28
27
|
'register_company',
|
|
29
28
|
'BaseCompany',
|
|
30
|
-
'DatabaseManager',
|
|
31
29
|
'QueryService',
|
|
32
30
|
'SqlService',
|
|
33
31
|
'ExcelService',
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
8
|
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
9
9
|
from iatoolkit.repositories.llm_query_repo import LLMQueryRepo
|
|
10
|
-
|
|
11
10
|
from iatoolkit.services.prompt_manager_service import PromptService
|
|
12
11
|
from iatoolkit.repositories.models import Company, Function, PromptCategory
|
|
13
12
|
from iatoolkit import IAToolkit
|
|
@@ -22,22 +21,14 @@ class BaseCompany(ABC):
|
|
|
22
21
|
self.prompt_service: PromptService = injector.get(PromptService)
|
|
23
22
|
self.company: Company | None = None
|
|
24
23
|
|
|
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
24
|
def _create_company(self,
|
|
30
25
|
short_name: str,
|
|
31
26
|
name: str,
|
|
32
27
|
parameters: dict | None = None,
|
|
33
|
-
branding: dict | None = None,
|
|
34
|
-
onboarding_cards: dict | None = None,
|
|
35
28
|
) -> Company:
|
|
36
29
|
company_obj = Company(short_name=short_name,
|
|
37
30
|
name=name,
|
|
38
|
-
parameters=parameters
|
|
39
|
-
branding=branding,
|
|
40
|
-
onboarding_cards=onboarding_cards)
|
|
31
|
+
parameters=parameters)
|
|
41
32
|
self.company = self.profile_repo.create_company(company_obj)
|
|
42
33
|
return self.company
|
|
43
34
|
|
|
@@ -77,17 +68,6 @@ class BaseCompany(ABC):
|
|
|
77
68
|
**kwargs
|
|
78
69
|
)
|
|
79
70
|
|
|
80
|
-
|
|
81
|
-
@abstractmethod
|
|
82
|
-
# initialize all the database tables needed
|
|
83
|
-
def register_company(self):
|
|
84
|
-
raise NotImplementedError("La subclase debe implementar el método create_company()")
|
|
85
|
-
|
|
86
|
-
@abstractmethod
|
|
87
|
-
# get context specific for this company
|
|
88
|
-
def get_company_context(self, **kwargs) -> str:
|
|
89
|
-
raise NotImplementedError("La subclase debe implementar el método get_company_context()")
|
|
90
|
-
|
|
91
71
|
@abstractmethod
|
|
92
72
|
# get context specific for this company
|
|
93
73
|
def get_user_info(self, user_identifier: str) -> dict:
|
|
@@ -98,11 +78,6 @@ class BaseCompany(ABC):
|
|
|
98
78
|
def handle_request(self, tag: str, params: dict) -> dict:
|
|
99
79
|
raise NotImplementedError("La subclase debe implementar el método handle_request()")
|
|
100
80
|
|
|
101
|
-
@abstractmethod
|
|
102
|
-
# get context specific for the query
|
|
103
|
-
def start_execution(self):
|
|
104
|
-
raise NotImplementedError("La subclase debe implementar el método start_execution()")
|
|
105
|
-
|
|
106
81
|
@abstractmethod
|
|
107
82
|
# get context specific for the query
|
|
108
83
|
def get_metadata_from_filename(self, filename: str) -> dict:
|
|
@@ -31,10 +31,9 @@ class CompanyRegistry:
|
|
|
31
31
|
|
|
32
32
|
# save the created instance in the registry
|
|
33
33
|
self._company_instances[company_key] = company_instance
|
|
34
|
-
logging.info(f"company '{company_key}' instantiated")
|
|
35
34
|
|
|
36
35
|
except Exception as e:
|
|
37
|
-
logging.error(f"Error
|
|
36
|
+
logging.error(f"Error while creating company instance for {company_key}: {e}")
|
|
38
37
|
logging.exception(e)
|
|
39
38
|
raise
|
|
40
39
|
|
|
@@ -19,7 +19,7 @@ from werkzeug.middleware.proxy_fix import ProxyFix
|
|
|
19
19
|
from injector import Binder, Injector, singleton
|
|
20
20
|
from importlib.metadata import version as _pkg_version, PackageNotFoundError
|
|
21
21
|
|
|
22
|
-
IATOOLKIT_VERSION = "0.
|
|
22
|
+
IATOOLKIT_VERSION = "0.69.0"
|
|
23
23
|
|
|
24
24
|
# global variable for the unique instance of IAToolkit
|
|
25
25
|
_iatoolkit_instance: Optional['IAToolkit'] = None
|
|
@@ -293,7 +293,6 @@ class IAToolkit:
|
|
|
293
293
|
from iatoolkit.repositories.document_repo import DocumentRepo
|
|
294
294
|
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
295
295
|
from iatoolkit.repositories.llm_query_repo import LLMQueryRepo
|
|
296
|
-
|
|
297
296
|
from iatoolkit.repositories.vs_repo import VSRepo
|
|
298
297
|
from iatoolkit.repositories.tasks_repo import TaskRepo
|
|
299
298
|
|
|
@@ -318,6 +317,7 @@ class IAToolkit:
|
|
|
318
317
|
from iatoolkit.services.branding_service import BrandingService
|
|
319
318
|
from iatoolkit.services.i18n_service import I18nService
|
|
320
319
|
from iatoolkit.services.language_service import LanguageService
|
|
320
|
+
from iatoolkit.services.configuration_service import ConfigurationService
|
|
321
321
|
|
|
322
322
|
binder.bind(QueryService, to=QueryService)
|
|
323
323
|
binder.bind(TaskService, to=TaskService)
|
|
@@ -333,6 +333,7 @@ class IAToolkit:
|
|
|
333
333
|
binder.bind(BrandingService, to=BrandingService)
|
|
334
334
|
binder.bind(I18nService, to=I18nService)
|
|
335
335
|
binder.bind(LanguageService, to=LanguageService)
|
|
336
|
+
binder.bind(ConfigurationService, to=ConfigurationService)
|
|
336
337
|
|
|
337
338
|
def _bind_infrastructure(self, binder: Binder):
|
|
338
339
|
from iatoolkit.infra.llm_client import llmClient
|
|
@@ -359,9 +360,9 @@ class IAToolkit:
|
|
|
359
360
|
# instantiate all the registered companies
|
|
360
361
|
get_company_registry().instantiate_companies(self._injector)
|
|
361
362
|
|
|
362
|
-
# use the dispatcher to
|
|
363
|
+
# use the dispatcher to load the company config.yaml file and prepare the execution
|
|
363
364
|
dispatcher = self._injector.get(Dispatcher)
|
|
364
|
-
dispatcher.
|
|
365
|
+
dispatcher.load_company_configs()
|
|
365
366
|
|
|
366
367
|
def _setup_cli_commands(self):
|
|
367
368
|
from iatoolkit.cli_commands import register_core_commands
|
|
@@ -70,6 +70,11 @@ class DatabaseManager:
|
|
|
70
70
|
def remove_session(self):
|
|
71
71
|
self.scoped_session.remove()
|
|
72
72
|
|
|
73
|
+
def get_all_table_names(self) -> list[str]:
|
|
74
|
+
# Returns a list of all table names in the database
|
|
75
|
+
inspector = inspect(self._engine)
|
|
76
|
+
return inspector.get_table_names()
|
|
77
|
+
|
|
73
78
|
def get_table_schema(self,
|
|
74
79
|
table_name: str,
|
|
75
80
|
schema_name: str | None = None,
|
|
@@ -53,17 +53,12 @@ class Company(Base):
|
|
|
53
53
|
id = Column(Integer, primary_key=True)
|
|
54
54
|
short_name = Column(String(20), nullable=False, unique=True, index=True)
|
|
55
55
|
name = Column(String(256), nullable=False)
|
|
56
|
-
default_language = Column(String(5), nullable=False, default='es')
|
|
57
56
|
|
|
58
57
|
# encrypted api-key
|
|
59
58
|
openai_api_key = Column(String, nullable=True)
|
|
60
59
|
gemini_api_key = Column(String, nullable=True)
|
|
61
|
-
|
|
62
|
-
branding = Column(JSON, nullable=True)
|
|
63
|
-
onboarding_cards = Column(JSON, nullable=True)
|
|
64
60
|
parameters = Column(JSON, nullable=True)
|
|
65
61
|
created_at = Column(DateTime, default=datetime.now)
|
|
66
|
-
allow_jwt = Column(Boolean, default=True, nullable=True)
|
|
67
62
|
|
|
68
63
|
documents = relationship("Document",
|
|
69
64
|
back_populates="company",
|
|
@@ -74,10 +74,6 @@ class ProfileRepo:
|
|
|
74
74
|
if company:
|
|
75
75
|
if company.parameters != new_company.parameters:
|
|
76
76
|
company.parameters = new_company.parameters
|
|
77
|
-
if company.branding != new_company.branding:
|
|
78
|
-
company.branding = new_company.branding
|
|
79
|
-
if company.onboarding_cards != new_company.onboarding_cards:
|
|
80
|
-
company.onboarding_cards = new_company.onboarding_cards
|
|
81
77
|
else:
|
|
82
78
|
# Si la compañía no existe, la añade a la sesión.
|
|
83
79
|
self.session.add(new_company)
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# IAToolkit is open source software.
|
|
5
5
|
|
|
6
6
|
from iatoolkit.repositories.models import Company
|
|
7
|
+
from iatoolkit.services.configuration_service import ConfigurationService
|
|
7
8
|
from injector import inject
|
|
8
9
|
|
|
9
10
|
|
|
@@ -12,7 +13,8 @@ class BrandingService:
|
|
|
12
13
|
Branding configuration for IAToolkit
|
|
13
14
|
"""
|
|
14
15
|
@inject
|
|
15
|
-
def __init__(self):
|
|
16
|
+
def __init__(self, config_service: ConfigurationService):
|
|
17
|
+
self.config_service = config_service
|
|
16
18
|
"""
|
|
17
19
|
Define los estilos de branding por defecto para la aplicación.
|
|
18
20
|
"""
|
|
@@ -67,15 +69,15 @@ class BrandingService:
|
|
|
67
69
|
"send_button_color": "#212529" # Gris oscuro/casi negro por defecto
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
def get_company_branding(self,
|
|
72
|
+
def get_company_branding(self, company_short_name: str) -> dict:
|
|
71
73
|
"""
|
|
72
74
|
Retorna los estilos de branding finales para una compañía,
|
|
73
75
|
fusionando los valores por defecto con los personalizados.
|
|
74
76
|
"""
|
|
75
77
|
final_branding_values = self._default_branding.copy()
|
|
78
|
+
branding_data = self.config_service.get_configuration(company_short_name, 'branding')
|
|
79
|
+
final_branding_values.update(branding_data)
|
|
76
80
|
|
|
77
|
-
if company and company.branding:
|
|
78
|
-
final_branding_values.update(company.branding)
|
|
79
81
|
|
|
80
82
|
# Función para convertir HEX a RGB
|
|
81
83
|
def hex_to_rgb(hex_color):
|
|
@@ -137,8 +139,11 @@ class BrandingService:
|
|
|
137
139
|
}}
|
|
138
140
|
"""
|
|
139
141
|
|
|
142
|
+
# get the company name from configuration for the branding render
|
|
143
|
+
company_name = self.config_service.get_configuration(company_short_name, 'name')
|
|
144
|
+
|
|
140
145
|
return {
|
|
141
|
-
"name":
|
|
146
|
+
"name": company_name,
|
|
142
147
|
"primary_text_style": primary_text_style,
|
|
143
148
|
"secondary_text_style": secondary_text_style,
|
|
144
149
|
"tertiary_text_style": tertiary_text_style,
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
+
# Product: IAToolkit
|
|
3
|
+
#
|
|
4
|
+
# IAToolkit is open source software.
|
|
5
|
+
|
|
6
|
+
from iatoolkit.common.util import Utility
|
|
7
|
+
from iatoolkit.services.configuration_service import ConfigurationService
|
|
8
|
+
from iatoolkit.services.sql_service import SqlService
|
|
9
|
+
from iatoolkit.common.exceptions import IAToolkitException
|
|
10
|
+
import logging
|
|
11
|
+
from injector import inject
|
|
12
|
+
import os
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CompanyContextService:
|
|
16
|
+
"""
|
|
17
|
+
Responsible for building the complete context string for a given company
|
|
18
|
+
to be sent to the Language Model.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
@inject
|
|
22
|
+
def __init__(self,
|
|
23
|
+
sql_service: SqlService,
|
|
24
|
+
utility: Utility,
|
|
25
|
+
config_service: ConfigurationService):
|
|
26
|
+
self.sql_service = sql_service
|
|
27
|
+
self.utility = utility
|
|
28
|
+
self.config_service = config_service
|
|
29
|
+
|
|
30
|
+
def get_company_context(self, company_short_name: str) -> str:
|
|
31
|
+
"""
|
|
32
|
+
Builds the full context by aggregating three sources:
|
|
33
|
+
1. Static context files (Markdown).
|
|
34
|
+
2. Static schema files (YAML for APIs, etc.).
|
|
35
|
+
3. Dynamic SQL database schema from the live connection.
|
|
36
|
+
"""
|
|
37
|
+
context_parts = []
|
|
38
|
+
|
|
39
|
+
# 1. Context from Markdown (context/*.md) and yaml (schema/*.yaml) files
|
|
40
|
+
try:
|
|
41
|
+
md_context = self._get_static_file_context(company_short_name)
|
|
42
|
+
if md_context:
|
|
43
|
+
context_parts.append(md_context)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
logging.warning(f"Could not load Markdown context for '{company_short_name}': {e}")
|
|
46
|
+
|
|
47
|
+
# 2. Context from company-specific Python logic (SQL schemas)
|
|
48
|
+
try:
|
|
49
|
+
sql_context = self._get_sql_schema_context(company_short_name)
|
|
50
|
+
if sql_context:
|
|
51
|
+
context_parts.append(sql_context)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
logging.warning(f"Could not generate SQL context for '{company_short_name}': {e}")
|
|
54
|
+
|
|
55
|
+
# Join all parts with a clear separator
|
|
56
|
+
return "\n\n---\n\n".join(context_parts)
|
|
57
|
+
|
|
58
|
+
def _get_static_file_context(self, company_short_name: str) -> str:
|
|
59
|
+
# Get context from .md and .yaml schema files.
|
|
60
|
+
static_context = ''
|
|
61
|
+
|
|
62
|
+
# Part 1: Markdown context files
|
|
63
|
+
context_dir = f'companies/{company_short_name}/context'
|
|
64
|
+
if os.path.exists(context_dir):
|
|
65
|
+
context_files = self.utility.get_files_by_extension(context_dir, '.md', return_extension=True)
|
|
66
|
+
for file in context_files:
|
|
67
|
+
filepath = os.path.join(context_dir, file)
|
|
68
|
+
static_context += self.utility.load_markdown_context(filepath)
|
|
69
|
+
|
|
70
|
+
# Part 2: YAML schema files
|
|
71
|
+
schema_dir = f'companies/{company_short_name}/schema'
|
|
72
|
+
if os.path.exists(schema_dir):
|
|
73
|
+
schema_files = self.utility.get_files_by_extension(schema_dir, '.yaml', return_extension=True)
|
|
74
|
+
for file in schema_files:
|
|
75
|
+
schema_name = file.split('.')[0] # Use full filename as entity name
|
|
76
|
+
filepath = os.path.join(schema_dir, file)
|
|
77
|
+
static_context += self.utility.generate_context_for_schema(schema_name, filepath)
|
|
78
|
+
|
|
79
|
+
return static_context
|
|
80
|
+
|
|
81
|
+
def _get_sql_schema_context(self, company_short_name: str) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Generates the SQL schema context by inspecting live database connections
|
|
84
|
+
based on the flexible company.yaml configuration.
|
|
85
|
+
It supports including all tables and providing specific overrides for a subset of them.
|
|
86
|
+
"""
|
|
87
|
+
data_sources_config = self.config_service.get_configuration(company_short_name, 'data_sources')
|
|
88
|
+
if not data_sources_config or not data_sources_config.get('sql'):
|
|
89
|
+
return ''
|
|
90
|
+
|
|
91
|
+
sql_context = ''
|
|
92
|
+
for source in data_sources_config.get('sql', []):
|
|
93
|
+
db_name = source.get('database')
|
|
94
|
+
if not db_name:
|
|
95
|
+
continue
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
db_manager = self.sql_service.get_database_manager(db_name)
|
|
99
|
+
except IAToolkitException as e:
|
|
100
|
+
logging.warning(f"Could not get DB manager for '{db_name}': {e}")
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
db_description = source.get('description', '')
|
|
104
|
+
sql_context += f"{db_description}\n" if db_description else ""
|
|
105
|
+
|
|
106
|
+
# 1. get the list of tables to process.
|
|
107
|
+
tables_to_process = []
|
|
108
|
+
if source.get('include_all_tables', False):
|
|
109
|
+
all_tables = db_manager.get_all_table_names()
|
|
110
|
+
tables_to_exclude = set(source.get('exclude_tables', []))
|
|
111
|
+
tables_to_process = [t for t in all_tables if t not in tables_to_exclude]
|
|
112
|
+
elif 'tables' in source:
|
|
113
|
+
# if not include_all_tables, use the list of tables explicitly specified in the map.
|
|
114
|
+
tables_to_process = list(source['tables'].keys())
|
|
115
|
+
|
|
116
|
+
# 2. get the global list of columns to exclude.
|
|
117
|
+
global_exclude_columns = source.get('exclude_columns', [])
|
|
118
|
+
|
|
119
|
+
# 3. get the overrides for specific tables.
|
|
120
|
+
table_overrides = source.get('tables', {})
|
|
121
|
+
|
|
122
|
+
# 3. iterate over the tables.
|
|
123
|
+
for table_name in tables_to_process:
|
|
124
|
+
try:
|
|
125
|
+
# 4. get the table specific configuration.
|
|
126
|
+
table_config = table_overrides.get(table_name, {})
|
|
127
|
+
|
|
128
|
+
# 5. define the schema name, using the override if it exists.
|
|
129
|
+
schema_name = table_config.get('schema_name', table_name)
|
|
130
|
+
|
|
131
|
+
# 6. define the list of columns to exclude, (local vs. global).
|
|
132
|
+
local_exclude_columns = table_config.get('exclude_columns')
|
|
133
|
+
final_exclude_columns = local_exclude_columns if local_exclude_columns is not None else global_exclude_columns
|
|
134
|
+
|
|
135
|
+
# 7. get the table schema definition.
|
|
136
|
+
table_definition = db_manager.get_table_schema(
|
|
137
|
+
table_name=table_name,
|
|
138
|
+
schema_name=schema_name,
|
|
139
|
+
exclude_columns=final_exclude_columns
|
|
140
|
+
)
|
|
141
|
+
sql_context += table_definition
|
|
142
|
+
except (KeyError, RuntimeError) as e:
|
|
143
|
+
logging.warning(f"Could not generate schema for table '{table_name}': {e}")
|
|
144
|
+
|
|
145
|
+
return sql_context
|