iatoolkit 0.3.9__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of iatoolkit might be problematic. Click here for more details.
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/PKG-INFO +43 -37
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/pyproject.toml +1 -1
- iatoolkit-0.4.1/readme.md +49 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/__init__.py +9 -3
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/cli_commands.py +2 -10
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/company_registry.py +6 -8
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit.egg-info/PKG-INFO +43 -37
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/benchmark_service.py +1 -1
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/dispatcher_service.py +37 -23
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/file_processor_service.py +28 -5
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/load_documents_service.py +75 -22
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/prompt_manager_service.py +2 -1
- iatoolkit-0.3.9/readme.md +0 -43
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/requirements.txt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/setup.cfg +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/base_company.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/iatoolkit.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/system_prompts/arquitectura.prompt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/system_prompts/format_styles.prompt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/system_prompts/query_main.prompt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit/system_prompts/sql_rules.prompt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit.egg-info/SOURCES.txt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/iatoolkit.egg-info/top_level.txt +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/__init__.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/api_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/document_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/excel_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/history_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/jwt_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/mail_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/profile_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/query_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/search_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/sql_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/tasks_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/user_feedback_service.py +0 -0
- {iatoolkit-0.3.9 → iatoolkit-0.4.1}/src/services/user_session_context_service.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iatoolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: IAToolkit
|
|
5
5
|
Author: Fernando Libedinsky
|
|
6
6
|
License-Expression: MIT
|
|
@@ -207,46 +207,52 @@ Requires-Dist: yarl==1.18.3
|
|
|
207
207
|
Requires-Dist: zipp==3.21.0
|
|
208
208
|
Requires-Dist: zstandard==0.23.0
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
|
|
211
|
+
<div align="center">
|
|
212
|
+
<h1>IAToolkit</h1>
|
|
213
|
+
<p><strong>The Open-Source Framework for Building AI Chatbots on Your Private Data.</strong></p>
|
|
214
|
+
</div>
|
|
211
215
|
|
|
212
216
|
IAToolkit is a comprehensive, open-source framework designed for building enterprise-grade
|
|
213
217
|
AI chatbots and conversational applications.
|
|
214
|
-
|
|
218
|
+
With IAToolkit, you can build production-ready, context-aware chatbots and agents that
|
|
219
|
+
can query relational databases, perform semantic searches on documents,
|
|
220
|
+
and connect to your internal APIs in minutes.
|
|
221
|
+
|
|
222
|
+
IAToolkit bridges the gap between powerful LLMs and your company's data.
|
|
223
|
+
|
|
215
224
|
|
|
216
225
|
## 🚀 Key Features
|
|
217
|
-
- **Universal LLM Integration**: OpenAI GPT, Google Gemini
|
|
218
|
-
- **Template System**: Jinja2-powered prompt templates with variables
|
|
219
|
-
- **Context Management**: Maintain conversation context across sessions
|
|
220
|
-
|
|
221
|
-
### 🔒 **Enterprise Security**
|
|
222
|
-
- **JWT Authentication**: Secure token-based authentication
|
|
223
|
-
- **Session Management**: Redis-backed secure sessions
|
|
224
|
-
- **CORS Configuration**: Flexible cross-origin resource sharing
|
|
225
|
-
|
|
226
|
-
### 🛠 **Function Calling & Tools**
|
|
227
|
-
- **Native Function Calls**: Direct integration with LLM function calling
|
|
228
|
-
- **Custom Tools**: Build and register custom tools for your chatbot
|
|
229
|
-
- **SQL Query Generation**: Natural language to SQL conversion
|
|
230
|
-
- **API Integrations**: Connect to external services and APIs
|
|
231
|
-
|
|
232
|
-
### 🗄 **Database & Storage**
|
|
233
|
-
- **Multi-Database Support**: PostgreSQL, MySQL, SQLite via SQLAlchemy
|
|
234
|
-
- **Vector Store Integration**: Semantic search and retrieval
|
|
235
|
-
- **Document Processing**: PDF, Word, Excel, and text file handling
|
|
236
|
-
|
|
237
|
-
### 📊 **Analytics & Monitoring**
|
|
238
|
-
- **Query Logging**: Track all LLM interactions
|
|
239
|
-
- **Performance Metrics**: Response times, token usage, costs
|
|
240
|
-
- **Benchmarking**: Compare model performance
|
|
241
|
-
- **Task Management**: Async task processing with status tracking
|
|
242
|
-
|
|
243
|
-
### 🔧 **Developer Experience**
|
|
244
|
-
- **Dependency Injection**: Clean, testable architecture
|
|
245
|
-
- **CLI Tools**: Command-line interface for common tasks
|
|
246
|
-
- **Hot Reloading**: Development-friendly configuration
|
|
247
|
-
- **Comprehensive Logging**: Debug and monitor easily
|
|
248
|
-
|
|
249
|
-
## License
|
|
250
|
-
MIT License
|
|
251
226
|
|
|
227
|
+
* **🔗 Unified Data Connection**:
|
|
228
|
+
* **Natural Language to SQL**: Let your chatbot query relational databases (PostgreSQL, MySQL, SQLite) using everyday language.
|
|
229
|
+
* **Semantic Document Search**: Automatically chunk, embed, and search across your private documents (PDFs, Word, etc.) to provide contextually accurate answers.
|
|
230
|
+
|
|
231
|
+
* **🏢 Enterprise-Ready Multi-Tenancy**:
|
|
232
|
+
* Deploy isolated "Company" modules, each with its own data, tools, and context. Perfect for SaaS products or internal departmental agents.
|
|
233
|
+
|
|
234
|
+
* **🧠 LLM Agnostic**:
|
|
235
|
+
* Switch between **OpenAI (GPT-*)** and **Google (Gemini-*)** with a single line change in your configuration. No code refactoring needed.
|
|
236
|
+
|
|
237
|
+
* **🛠️ Developer-First Experience**:
|
|
238
|
+
* Built with a clean, **Dependency Injection** architecture.
|
|
239
|
+
* High-quality code base with **90%+ test coverage**.
|
|
240
|
+
* Powerful Flask-based **CLI** for database setup, API key generation, and more.
|
|
241
|
+
|
|
242
|
+
* **🔒 Security & Observability Built-In**:
|
|
243
|
+
* Comes with JWT-based authentication, user management, and secure session handling out of the box.
|
|
244
|
+
* Full traceability with detailed logging of all queries, function calls, token usage, and costs.
|
|
245
|
+
|
|
246
|
+
## ⚡ Quick Start: Create a Custom Tool in 30 Seconds
|
|
247
|
+
|
|
248
|
+
See how easy it is to give your AI a new skill. Just define a method inside your Company class and describe it.
|
|
249
|
+
IAToolkit handles the rest.
|
|
250
|
+
|
|
251
|
+
## 🤝 Contributing
|
|
252
|
+
|
|
253
|
+
We welcome contributions! Whether it's adding a new feature, improving documentation, or fixing a bug,
|
|
254
|
+
please feel free to open a pull request.
|
|
255
|
+
|
|
256
|
+
## 📄 License
|
|
252
257
|
|
|
258
|
+
IAToolkit is open-source and licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
<div align="center">
|
|
3
|
+
<h1>IAToolkit</h1>
|
|
4
|
+
<p><strong>The Open-Source Framework for Building AI Chatbots on Your Private Data.</strong></p>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
IAToolkit is a comprehensive, open-source framework designed for building enterprise-grade
|
|
8
|
+
AI chatbots and conversational applications.
|
|
9
|
+
With IAToolkit, you can build production-ready, context-aware chatbots and agents that
|
|
10
|
+
can query relational databases, perform semantic searches on documents,
|
|
11
|
+
and connect to your internal APIs in minutes.
|
|
12
|
+
|
|
13
|
+
IAToolkit bridges the gap between powerful LLMs and your company's data.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## 🚀 Key Features
|
|
17
|
+
|
|
18
|
+
* **🔗 Unified Data Connection**:
|
|
19
|
+
* **Natural Language to SQL**: Let your chatbot query relational databases (PostgreSQL, MySQL, SQLite) using everyday language.
|
|
20
|
+
* **Semantic Document Search**: Automatically chunk, embed, and search across your private documents (PDFs, Word, etc.) to provide contextually accurate answers.
|
|
21
|
+
|
|
22
|
+
* **🏢 Enterprise-Ready Multi-Tenancy**:
|
|
23
|
+
* Deploy isolated "Company" modules, each with its own data, tools, and context. Perfect for SaaS products or internal departmental agents.
|
|
24
|
+
|
|
25
|
+
* **🧠 LLM Agnostic**:
|
|
26
|
+
* Switch between **OpenAI (GPT-*)** and **Google (Gemini-*)** with a single line change in your configuration. No code refactoring needed.
|
|
27
|
+
|
|
28
|
+
* **🛠️ Developer-First Experience**:
|
|
29
|
+
* Built with a clean, **Dependency Injection** architecture.
|
|
30
|
+
* High-quality code base with **90%+ test coverage**.
|
|
31
|
+
* Powerful Flask-based **CLI** for database setup, API key generation, and more.
|
|
32
|
+
|
|
33
|
+
* **🔒 Security & Observability Built-In**:
|
|
34
|
+
* Comes with JWT-based authentication, user management, and secure session handling out of the box.
|
|
35
|
+
* Full traceability with detailed logging of all queries, function calls, token usage, and costs.
|
|
36
|
+
|
|
37
|
+
## ⚡ Quick Start: Create a Custom Tool in 30 Seconds
|
|
38
|
+
|
|
39
|
+
See how easy it is to give your AI a new skill. Just define a method inside your Company class and describe it.
|
|
40
|
+
IAToolkit handles the rest.
|
|
41
|
+
|
|
42
|
+
## 🤝 Contributing
|
|
43
|
+
|
|
44
|
+
We welcome contributions! Whether it's adding a new feature, improving documentation, or fixing a bug,
|
|
45
|
+
please feel free to open a pull request.
|
|
46
|
+
|
|
47
|
+
## 📄 License
|
|
48
|
+
|
|
49
|
+
IAToolkit is open-source and licensed under the [MIT License](LICENSE).
|
|
@@ -21,13 +21,15 @@ from services.excel_service import ExcelService
|
|
|
21
21
|
from services.dispatcher_service import Dispatcher
|
|
22
22
|
from services.document_service import DocumentService
|
|
23
23
|
from services.search_service import SearchService
|
|
24
|
-
from services.
|
|
24
|
+
from services.load_documents_service import LoadDocumentsService
|
|
25
25
|
from repositories.profile_repo import ProfileRepo
|
|
26
26
|
from repositories.llm_query_repo import LLMQueryRepo
|
|
27
|
+
from services.query_service import QueryService
|
|
28
|
+
from services.prompt_manager_service import PromptService
|
|
27
29
|
from repositories.database_manager import DatabaseManager
|
|
28
30
|
from infra.call_service import CallServiceClient
|
|
29
31
|
from common.util import Utility
|
|
30
|
-
from repositories.models import Base, Company, Function, TaskType
|
|
32
|
+
from repositories.models import Base, Company, Function, TaskType, Prompt, PromptCategory
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
__all__ = [
|
|
@@ -40,10 +42,12 @@ __all__ = [
|
|
|
40
42
|
'ExcelService',
|
|
41
43
|
'Dispatcher',
|
|
42
44
|
'DocumentService',
|
|
43
|
-
'QueryService',
|
|
44
45
|
'SearchService',
|
|
46
|
+
'QueryService',
|
|
47
|
+
'LoadDocumentsService',
|
|
45
48
|
'ProfileRepo',
|
|
46
49
|
'LLMQueryRepo',
|
|
50
|
+
'PromptService',
|
|
47
51
|
'DatabaseManager',
|
|
48
52
|
'CallServiceClient',
|
|
49
53
|
'Utility',
|
|
@@ -51,4 +55,6 @@ __all__ = [
|
|
|
51
55
|
'Function',
|
|
52
56
|
'TaskType',
|
|
53
57
|
'Base',
|
|
58
|
+
'Prompt',
|
|
59
|
+
'PromptCategory'
|
|
54
60
|
]
|
|
@@ -24,6 +24,8 @@ def register_core_commands(app):
|
|
|
24
24
|
def setup_company(company_short_name: str):
|
|
25
25
|
"""⚙️ Genera una nueva API key para una compañía ya registrada."""
|
|
26
26
|
try:
|
|
27
|
+
dispatcher = IAToolkit.get_instance().get_injector().get(Dispatcher)
|
|
28
|
+
dispatcher.setup_all_companies()
|
|
27
29
|
profile_service = IAToolkit.get_instance().get_injector().get(ProfileService)
|
|
28
30
|
click.echo(f"🔑 Generando API key para '{company_short_name}'...")
|
|
29
31
|
result = profile_service.new_api_key(company_short_name)
|
|
@@ -64,14 +66,4 @@ def register_core_commands(app):
|
|
|
64
66
|
logging.exception(e)
|
|
65
67
|
click.echo(f"Error: {str(e)}")
|
|
66
68
|
|
|
67
|
-
@app.cli.command("load")
|
|
68
|
-
def load_documents():
|
|
69
|
-
from services.load_documents_service import LoadDocumentsService
|
|
70
69
|
|
|
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)}")
|
|
@@ -15,27 +15,21 @@ class CompanyRegistry:
|
|
|
15
15
|
def __init__(self):
|
|
16
16
|
self._company_classes: Dict[str, Type[BaseCompany]] = {}
|
|
17
17
|
self._company_instances: Dict[str, BaseCompany] = {}
|
|
18
|
-
self._injector = None
|
|
19
18
|
|
|
20
|
-
def set_injector(self, injector) -> None:
|
|
21
|
-
"""Establece el injector para crear instancias con dependencias"""
|
|
22
|
-
self._injector = injector
|
|
23
19
|
|
|
24
|
-
def instantiate_companies(self) -> Dict[str, BaseCompany]:
|
|
20
|
+
def instantiate_companies(self, injector) -> Dict[str, BaseCompany]:
|
|
25
21
|
"""
|
|
26
22
|
Instancia todas las empresas registradas con inyección de dependencias.
|
|
27
23
|
|
|
28
24
|
Returns:
|
|
29
25
|
Dict con instancias de empresas {name: instance}
|
|
30
26
|
"""
|
|
31
|
-
if not self._injector:
|
|
32
|
-
raise RuntimeError("Injector no configurado. Llame a set_injector() primero.")
|
|
33
27
|
|
|
34
28
|
for company_key, company_class in self._company_classes.items():
|
|
35
29
|
if company_key not in self._company_instances:
|
|
36
30
|
try:
|
|
37
31
|
# use de injector to create the instance
|
|
38
|
-
company_instance =
|
|
32
|
+
company_instance = injector.get(company_class)
|
|
39
33
|
self._company_instances[company_key] = company_instance
|
|
40
34
|
logging.info(f"company '{company_key}' created in dispatcher")
|
|
41
35
|
|
|
@@ -46,6 +40,10 @@ class CompanyRegistry:
|
|
|
46
40
|
|
|
47
41
|
return self._company_instances.copy()
|
|
48
42
|
|
|
43
|
+
def get_all_company_instances(self) -> Dict[str, BaseCompany]:
|
|
44
|
+
"""Devuelve un diccionario con todas las instancias de empresas creadas."""
|
|
45
|
+
return self._company_instances.copy()
|
|
46
|
+
|
|
49
47
|
def get_registered_companies(self) -> Dict[str, Type[BaseCompany]]:
|
|
50
48
|
return self._company_classes.copy()
|
|
51
49
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iatoolkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: IAToolkit
|
|
5
5
|
Author: Fernando Libedinsky
|
|
6
6
|
License-Expression: MIT
|
|
@@ -207,46 +207,52 @@ Requires-Dist: yarl==1.18.3
|
|
|
207
207
|
Requires-Dist: zipp==3.21.0
|
|
208
208
|
Requires-Dist: zstandard==0.23.0
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
|
|
211
|
+
<div align="center">
|
|
212
|
+
<h1>IAToolkit</h1>
|
|
213
|
+
<p><strong>The Open-Source Framework for Building AI Chatbots on Your Private Data.</strong></p>
|
|
214
|
+
</div>
|
|
211
215
|
|
|
212
216
|
IAToolkit is a comprehensive, open-source framework designed for building enterprise-grade
|
|
213
217
|
AI chatbots and conversational applications.
|
|
214
|
-
|
|
218
|
+
With IAToolkit, you can build production-ready, context-aware chatbots and agents that
|
|
219
|
+
can query relational databases, perform semantic searches on documents,
|
|
220
|
+
and connect to your internal APIs in minutes.
|
|
221
|
+
|
|
222
|
+
IAToolkit bridges the gap between powerful LLMs and your company's data.
|
|
223
|
+
|
|
215
224
|
|
|
216
225
|
## 🚀 Key Features
|
|
217
|
-
- **Universal LLM Integration**: OpenAI GPT, Google Gemini
|
|
218
|
-
- **Template System**: Jinja2-powered prompt templates with variables
|
|
219
|
-
- **Context Management**: Maintain conversation context across sessions
|
|
220
|
-
|
|
221
|
-
### 🔒 **Enterprise Security**
|
|
222
|
-
- **JWT Authentication**: Secure token-based authentication
|
|
223
|
-
- **Session Management**: Redis-backed secure sessions
|
|
224
|
-
- **CORS Configuration**: Flexible cross-origin resource sharing
|
|
225
|
-
|
|
226
|
-
### 🛠 **Function Calling & Tools**
|
|
227
|
-
- **Native Function Calls**: Direct integration with LLM function calling
|
|
228
|
-
- **Custom Tools**: Build and register custom tools for your chatbot
|
|
229
|
-
- **SQL Query Generation**: Natural language to SQL conversion
|
|
230
|
-
- **API Integrations**: Connect to external services and APIs
|
|
231
|
-
|
|
232
|
-
### 🗄 **Database & Storage**
|
|
233
|
-
- **Multi-Database Support**: PostgreSQL, MySQL, SQLite via SQLAlchemy
|
|
234
|
-
- **Vector Store Integration**: Semantic search and retrieval
|
|
235
|
-
- **Document Processing**: PDF, Word, Excel, and text file handling
|
|
236
|
-
|
|
237
|
-
### 📊 **Analytics & Monitoring**
|
|
238
|
-
- **Query Logging**: Track all LLM interactions
|
|
239
|
-
- **Performance Metrics**: Response times, token usage, costs
|
|
240
|
-
- **Benchmarking**: Compare model performance
|
|
241
|
-
- **Task Management**: Async task processing with status tracking
|
|
242
|
-
|
|
243
|
-
### 🔧 **Developer Experience**
|
|
244
|
-
- **Dependency Injection**: Clean, testable architecture
|
|
245
|
-
- **CLI Tools**: Command-line interface for common tasks
|
|
246
|
-
- **Hot Reloading**: Development-friendly configuration
|
|
247
|
-
- **Comprehensive Logging**: Debug and monitor easily
|
|
248
|
-
|
|
249
|
-
## License
|
|
250
|
-
MIT License
|
|
251
226
|
|
|
227
|
+
* **🔗 Unified Data Connection**:
|
|
228
|
+
* **Natural Language to SQL**: Let your chatbot query relational databases (PostgreSQL, MySQL, SQLite) using everyday language.
|
|
229
|
+
* **Semantic Document Search**: Automatically chunk, embed, and search across your private documents (PDFs, Word, etc.) to provide contextually accurate answers.
|
|
230
|
+
|
|
231
|
+
* **🏢 Enterprise-Ready Multi-Tenancy**:
|
|
232
|
+
* Deploy isolated "Company" modules, each with its own data, tools, and context. Perfect for SaaS products or internal departmental agents.
|
|
233
|
+
|
|
234
|
+
* **🧠 LLM Agnostic**:
|
|
235
|
+
* Switch between **OpenAI (GPT-*)** and **Google (Gemini-*)** with a single line change in your configuration. No code refactoring needed.
|
|
236
|
+
|
|
237
|
+
* **🛠️ Developer-First Experience**:
|
|
238
|
+
* Built with a clean, **Dependency Injection** architecture.
|
|
239
|
+
* High-quality code base with **90%+ test coverage**.
|
|
240
|
+
* Powerful Flask-based **CLI** for database setup, API key generation, and more.
|
|
241
|
+
|
|
242
|
+
* **🔒 Security & Observability Built-In**:
|
|
243
|
+
* Comes with JWT-based authentication, user management, and secure session handling out of the box.
|
|
244
|
+
* Full traceability with detailed logging of all queries, function calls, token usage, and costs.
|
|
245
|
+
|
|
246
|
+
## ⚡ Quick Start: Create a Custom Tool in 30 Seconds
|
|
247
|
+
|
|
248
|
+
See how easy it is to give your AI a new skill. Just define a method inside your Company class and describe it.
|
|
249
|
+
IAToolkit handles the rest.
|
|
250
|
+
|
|
251
|
+
## 🤝 Contributing
|
|
252
|
+
|
|
253
|
+
We welcome contributions! Whether it's adding a new feature, improving documentation, or fixing a bug,
|
|
254
|
+
please feel free to open a pull request.
|
|
255
|
+
|
|
256
|
+
## 📄 License
|
|
252
257
|
|
|
258
|
+
IAToolkit is open-source and licensed under the [MIT License](LICENSE).
|
|
@@ -65,7 +65,7 @@ class BenchmarkService:
|
|
|
65
65
|
|
|
66
66
|
company = self.profile_repo.get_company_by_short_name(company_short_name)
|
|
67
67
|
if not company:
|
|
68
|
-
raise IAToolkitException(IAToolkitException.ErrorType.CONFIG_ERROR, "Compañía
|
|
68
|
+
raise IAToolkitException(IAToolkitException.ErrorType.CONFIG_ERROR, f"Compañía {company_short_name} no encontrada.")
|
|
69
69
|
|
|
70
70
|
total_rows = len(df)
|
|
71
71
|
logging.info(f"Iniciando benchmark para {total_rows} casos de prueba desde el archivo: {file_path}")
|
|
@@ -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
|
-
|
|
41
|
-
self.
|
|
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,39 @@ 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.
|
|
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
|
-
self.company_registry.
|
|
68
|
-
|
|
81
|
+
self.company_registry.instantiate_companies(injector)
|
|
82
|
+
|
|
69
83
|
|
|
70
84
|
def start_execution(self):
|
|
71
85
|
"""Runs the startup logic for all registered companies."""
|
|
72
|
-
for company_name, company_instance in self.
|
|
86
|
+
for company_name, company_instance in self.company_instances.items():
|
|
73
87
|
logging.info(f'Starting execution for company: {company_name}')
|
|
74
88
|
company_instance.start_execution()
|
|
75
89
|
|
|
@@ -100,14 +114,14 @@ class Dispatcher:
|
|
|
100
114
|
i += 1
|
|
101
115
|
|
|
102
116
|
# register in the database every company class
|
|
103
|
-
for company in self.
|
|
117
|
+
for company in self.company_instances.values():
|
|
104
118
|
company.register_company()
|
|
105
119
|
|
|
106
120
|
def dispatch(self, company_name: str, action: str, **kwargs) -> str:
|
|
107
121
|
company_key = company_name.lower()
|
|
108
122
|
|
|
109
|
-
if company_key not in self.
|
|
110
|
-
available_companies = list(self.
|
|
123
|
+
if company_key not in self.company_instances:
|
|
124
|
+
available_companies = list(self.company_instances.keys())
|
|
111
125
|
raise IAToolkitException(
|
|
112
126
|
IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
|
|
113
127
|
f"Empresa '{company_name}' no configurada. Empresas disponibles: {available_companies}"
|
|
@@ -117,7 +131,7 @@ class Dispatcher:
|
|
|
117
131
|
if action in self.tool_handlers:
|
|
118
132
|
return self.tool_handlers[action](**kwargs)
|
|
119
133
|
|
|
120
|
-
company_instance = self.
|
|
134
|
+
company_instance = self.company_instances[company_name]
|
|
121
135
|
try:
|
|
122
136
|
return company_instance.handle_request(action, **kwargs)
|
|
123
137
|
except IAToolkitException as e:
|
|
@@ -130,7 +144,7 @@ class Dispatcher:
|
|
|
130
144
|
f"Error en function call '{action}': {str(e)}") from e
|
|
131
145
|
|
|
132
146
|
def get_company_context(self, company_name: str, **kwargs) -> str:
|
|
133
|
-
if company_name not in self.
|
|
147
|
+
if company_name not in self.company_instances:
|
|
134
148
|
raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
|
|
135
149
|
f"Empresa no configurada: {company_name}")
|
|
136
150
|
|
|
@@ -152,7 +166,7 @@ class Dispatcher:
|
|
|
152
166
|
filepath = os.path.join(schema_dir, file)
|
|
153
167
|
company_context += self.util.generate_context_for_schema(schema_name, filepath)
|
|
154
168
|
|
|
155
|
-
company_instance = self.
|
|
169
|
+
company_instance = self.company_instances[company_name]
|
|
156
170
|
try:
|
|
157
171
|
return company_context + company_instance.get_company_context(**kwargs)
|
|
158
172
|
except Exception as e:
|
|
@@ -180,7 +194,7 @@ class Dispatcher:
|
|
|
180
194
|
return tools
|
|
181
195
|
|
|
182
196
|
def get_user_info(self, company_name: str, user_identifier: str, is_local_user: bool) -> dict:
|
|
183
|
-
if company_name not in self.
|
|
197
|
+
if company_name not in self.company_instances:
|
|
184
198
|
raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
|
|
185
199
|
f"Empresa no configurada: {company_name}")
|
|
186
200
|
|
|
@@ -190,7 +204,7 @@ class Dispatcher:
|
|
|
190
204
|
raw_user_data = SessionManager.get('user', {})
|
|
191
205
|
else:
|
|
192
206
|
# source 2: external company user
|
|
193
|
-
company_instance = self.
|
|
207
|
+
company_instance = self.company_instances[company_name]
|
|
194
208
|
try:
|
|
195
209
|
raw_user_data = company_instance.get_user_info(user_identifier)
|
|
196
210
|
except Exception as e:
|
|
@@ -226,11 +240,11 @@ class Dispatcher:
|
|
|
226
240
|
return normalized_user
|
|
227
241
|
|
|
228
242
|
def get_metadata_from_filename(self, company_name: str, filename: str) -> dict:
|
|
229
|
-
if company_name not in self.
|
|
243
|
+
if company_name not in self.company_instances:
|
|
230
244
|
raise IAToolkitException(IAToolkitException.ErrorType.EXTERNAL_SOURCE_ERROR,
|
|
231
245
|
f"Empresa no configurada: {company_name}")
|
|
232
246
|
|
|
233
|
-
company_instance = self.
|
|
247
|
+
company_instance = self.company_instances[company_name]
|
|
234
248
|
try:
|
|
235
249
|
return company_instance.get_metadata_from_filename(filename)
|
|
236
250
|
except Exception as e:
|
|
@@ -240,14 +254,14 @@ class Dispatcher:
|
|
|
240
254
|
|
|
241
255
|
def get_company_instance(self, company_name: str):
|
|
242
256
|
"""Returns the instance for a given company name."""
|
|
243
|
-
return self.
|
|
257
|
+
return self.company_instances.get(company_name)
|
|
244
258
|
|
|
245
259
|
def get_registered_companies(self) -> dict:
|
|
246
|
-
"""
|
|
260
|
+
"""Gets all registered companies (for debugging/admin purposes)"""
|
|
247
261
|
return {
|
|
248
262
|
"registered_classes": list(self.company_registry.get_registered_companies().keys()),
|
|
249
|
-
"instantiated": list(self.
|
|
250
|
-
"count": len(self.
|
|
263
|
+
"instantiated": list(self.company_instances.keys()),
|
|
264
|
+
"count": len(self.company_instances)
|
|
251
265
|
}
|
|
252
266
|
|
|
253
267
|
|
|
@@ -7,26 +7,45 @@ from infra.connectors.file_connector import FileConnector
|
|
|
7
7
|
import logging
|
|
8
8
|
import os
|
|
9
9
|
from typing import Optional, Callable, Dict
|
|
10
|
+
from repositories.models import Company
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class FileProcessorConfig:
|
|
14
|
+
"""Configuration class for the FileProcessor."""
|
|
13
15
|
def __init__(
|
|
14
16
|
self,
|
|
15
17
|
filters: Dict,
|
|
16
|
-
|
|
18
|
+
callback: Callable[[Company, str, bytes, dict], None],
|
|
17
19
|
continue_on_error: bool = True,
|
|
18
20
|
log_file: str = 'file_processor.log',
|
|
19
21
|
echo: bool = False,
|
|
20
|
-
context: dict = None
|
|
22
|
+
context: dict = None
|
|
21
23
|
):
|
|
24
|
+
"""
|
|
25
|
+
Initializes the FileProcessor configuration.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
filters (Dict): A dictionary of filters to apply to file names.
|
|
29
|
+
Example: {'filename_contains': '.pdf'}
|
|
30
|
+
action (Callable): The function to execute for each processed file.
|
|
31
|
+
It receives filename (str), content (bytes), and context (dict).
|
|
32
|
+
continue_on_error (bool): If True, continues processing other files upon an error.
|
|
33
|
+
log_file (str): The path to the log file.
|
|
34
|
+
echo (bool): If True, prints progress to the console.
|
|
35
|
+
context (dict): A context dictionary passed to the action function.
|
|
36
|
+
"""
|
|
22
37
|
self.filters = filters
|
|
23
|
-
self.
|
|
38
|
+
self.callback = callback
|
|
24
39
|
self.continue_on_error = continue_on_error
|
|
25
40
|
self.log_file = log_file
|
|
26
41
|
self.echo = echo
|
|
27
42
|
self.context = context or {}
|
|
28
43
|
|
|
29
44
|
class FileProcessor:
|
|
45
|
+
"""
|
|
46
|
+
A generic service to process files from a given data source (connector).
|
|
47
|
+
It lists files, applies filters, and executes a specific action for each one.
|
|
48
|
+
"""
|
|
30
49
|
def __init__(self,
|
|
31
50
|
connector: FileConnector,
|
|
32
51
|
config: FileProcessorConfig,
|
|
@@ -45,6 +64,7 @@ class FileProcessor:
|
|
|
45
64
|
return logging.getLogger(__name__)
|
|
46
65
|
|
|
47
66
|
def process_files(self):
|
|
67
|
+
# Fetches files from the connector, filters them, and processes them.
|
|
48
68
|
try:
|
|
49
69
|
files = self.connector.list_files()
|
|
50
70
|
except Exception as e:
|
|
@@ -67,9 +87,12 @@ class FileProcessor:
|
|
|
67
87
|
|
|
68
88
|
content = self.connector.get_file_content(file_path)
|
|
69
89
|
|
|
70
|
-
# execute the
|
|
90
|
+
# execute the callback function
|
|
71
91
|
filename = os.path.basename(file_name)
|
|
72
|
-
self.config.
|
|
92
|
+
self.config.callback(company=self.config.context.get('company'),
|
|
93
|
+
filename=filename,
|
|
94
|
+
content=content,
|
|
95
|
+
context=self.config.context)
|
|
73
96
|
self.processed_files += 1
|
|
74
97
|
|
|
75
98
|
self.logger.info(f"Successfully processed file: {file_path}")
|
|
@@ -21,6 +21,10 @@ from typing import Dict
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class LoadDocumentsService:
|
|
24
|
+
"""
|
|
25
|
+
Orchestrates the process of loading, processing, and storing documents
|
|
26
|
+
from various sources for different companies.
|
|
27
|
+
"""
|
|
24
28
|
@inject
|
|
25
29
|
def __init__(self,
|
|
26
30
|
file_connector_factory: FileConnectorFactory,
|
|
@@ -38,7 +42,6 @@ class LoadDocumentsService:
|
|
|
38
42
|
self.vector_store = vector_store
|
|
39
43
|
self.file_connector_factory = file_connector_factory
|
|
40
44
|
self.dispatcher = dispatcher
|
|
41
|
-
self.company = None
|
|
42
45
|
|
|
43
46
|
# lower warnings
|
|
44
47
|
logging.getLogger().setLevel(logging.ERROR)
|
|
@@ -51,6 +54,17 @@ class LoadDocumentsService:
|
|
|
51
54
|
|
|
52
55
|
# load the files for all of the companies.
|
|
53
56
|
def load(self, doc_type: str = None):
|
|
57
|
+
"""
|
|
58
|
+
Loads documents for all companies based on their configuration.
|
|
59
|
+
It can load all document types or a specific one if provided.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
doc_type (str, optional): A specific document type to load.
|
|
63
|
+
If None, all configured types are loaded.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Dict: A dictionary with a summary message.
|
|
67
|
+
"""
|
|
54
68
|
# doc_type: an optional document_type for loading
|
|
55
69
|
files_loaded = 0
|
|
56
70
|
companies = self.profile_repo.get_companies()
|
|
@@ -61,7 +75,6 @@ class LoadDocumentsService:
|
|
|
61
75
|
continue
|
|
62
76
|
|
|
63
77
|
print(f"Cargando datos de ** {company.short_name} **")
|
|
64
|
-
self.company = company
|
|
65
78
|
|
|
66
79
|
# Si hay configuraciones de tipos de documento específicos
|
|
67
80
|
doc_types_config = load_config.get('document_types', {})
|
|
@@ -81,7 +94,34 @@ class LoadDocumentsService:
|
|
|
81
94
|
raise IAToolkitException(IAToolkitException.ErrorType.MISSING_PARAMETER,
|
|
82
95
|
f"Falta configurar conector en empresa {company.short_name}")
|
|
83
96
|
|
|
84
|
-
files_loaded += self.load_data_source(
|
|
97
|
+
files_loaded += self.load_data_source(company=company,
|
|
98
|
+
connector_config=connector)
|
|
99
|
+
|
|
100
|
+
return {'message': f'{files_loaded} files processed'}
|
|
101
|
+
|
|
102
|
+
def load_company_files(self, company: Company,
|
|
103
|
+
connector: dict,
|
|
104
|
+
predefined_metadata: Dict = None,
|
|
105
|
+
filters: Dict = None):
|
|
106
|
+
"""
|
|
107
|
+
Loads all files for a specific company using a given connector.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
company (Company): The company to load files for.
|
|
111
|
+
connector (dict): The connector configuration.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Dict: A dictionary with a summary message.
|
|
115
|
+
"""
|
|
116
|
+
if not connector:
|
|
117
|
+
raise IAToolkitException(IAToolkitException.ErrorType.MISSING_PARAMETER,
|
|
118
|
+
f"Falta configurar conector")
|
|
119
|
+
|
|
120
|
+
files_loaded = self.load_data_source(
|
|
121
|
+
company=company,
|
|
122
|
+
connector_config=connector,
|
|
123
|
+
predefined_metadata=predefined_metadata,
|
|
124
|
+
filters=filters)
|
|
85
125
|
|
|
86
126
|
return {'message': f'{files_loaded} files processed'}
|
|
87
127
|
|
|
@@ -99,36 +139,42 @@ class LoadDocumentsService:
|
|
|
99
139
|
# config specific filters
|
|
100
140
|
filters = type_config.get('filters', {"filename_contains": ".pdf"})
|
|
101
141
|
|
|
102
|
-
return self.load_data_source(
|
|
142
|
+
return self.load_data_source(company=company,
|
|
143
|
+
connector_config=connector,
|
|
144
|
+
predefined_metadata=predefined_metadata,
|
|
145
|
+
filters=filters)
|
|
103
146
|
|
|
104
|
-
def load_data_source(self, connector_config: Dict, predefined_metadata: Dict = None, filters: Dict = None):
|
|
147
|
+
def load_data_source(self, company: Company, connector_config: Dict, predefined_metadata: Dict = None, filters: Dict = None):
|
|
105
148
|
"""
|
|
106
|
-
|
|
149
|
+
Loads files from a data source using a connector and a FileProcessor.
|
|
107
150
|
|
|
108
151
|
Args:
|
|
109
|
-
connector_config:
|
|
110
|
-
predefined_metadata:
|
|
111
|
-
filters:
|
|
152
|
+
connector_config (Dict): The configuration for the file connector.
|
|
153
|
+
predefined_metadata (Dict, optional): Metadata to be added to all documents from this source.
|
|
154
|
+
filters (Dict, optional): Filters to apply to the files.
|
|
112
155
|
|
|
113
156
|
Returns:
|
|
114
|
-
int
|
|
157
|
+
int: The number of processed files.
|
|
115
158
|
"""
|
|
116
159
|
try:
|
|
117
|
-
# Si no se proporcionaron filtros, usar el predeterminado
|
|
118
160
|
if not filters:
|
|
119
161
|
filters = {"filename_contains": ".pdf"}
|
|
120
162
|
|
|
121
163
|
# Pasar metadata predefinida como parte del contexto al procesador
|
|
122
|
-
# para que esté disponible en la función
|
|
123
|
-
|
|
164
|
+
# para que esté disponible en la función load_file_callback
|
|
165
|
+
context = {
|
|
166
|
+
'company': company,
|
|
167
|
+
'metadata': {}
|
|
168
|
+
}
|
|
169
|
+
|
|
124
170
|
if predefined_metadata:
|
|
125
|
-
|
|
171
|
+
context['metadata'] = predefined_metadata
|
|
126
172
|
|
|
127
173
|
# config the processor
|
|
128
174
|
processor_config = FileProcessorConfig(
|
|
129
|
-
|
|
175
|
+
callback=self.load_file_callback,
|
|
176
|
+
context=context,
|
|
130
177
|
filters=filters,
|
|
131
|
-
action=self.load_file,
|
|
132
178
|
continue_on_error=True,
|
|
133
179
|
echo=True
|
|
134
180
|
)
|
|
@@ -144,14 +190,21 @@ class LoadDocumentsService:
|
|
|
144
190
|
logging.exception("Loading files error: %s", str(e))
|
|
145
191
|
return {"error": str(e)}
|
|
146
192
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
193
|
+
def load_file_callback(self, company: Company, filename: str, content: bytes, context: dict = {}):
|
|
194
|
+
"""
|
|
195
|
+
Processes a single file: extracts text, generates metadata, and saves it
|
|
196
|
+
to the relational database and the vector store.
|
|
197
|
+
This method is intended to be used as the 'action' for FileProcessor.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
company (Company): The company associated with the file.
|
|
201
|
+
filename (str): The name of the file.
|
|
202
|
+
content (bytes): The binary content of the file.
|
|
203
|
+
context (dict, optional): A context dictionary, may contain predefined metadata.
|
|
204
|
+
"""
|
|
152
205
|
|
|
153
206
|
# check if file exist in repositories
|
|
154
|
-
if self.doc_repo.get(
|
|
207
|
+
if self.doc_repo.get(company_id=company.id,filename=filename):
|
|
155
208
|
return
|
|
156
209
|
|
|
157
210
|
try:
|
|
@@ -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
|
-
|
|
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}")
|
iatoolkit-0.3.9/readme.md
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# iatoolkit
|
|
2
|
-
|
|
3
|
-
IAToolkit is a comprehensive, open-source framework designed for building enterprise-grade
|
|
4
|
-
AI chatbots and conversational applications.
|
|
5
|
-
Built on Flask with dependency injection, it provides a robust foundation for scalable AI solutions.
|
|
6
|
-
|
|
7
|
-
## 🚀 Key Features
|
|
8
|
-
- **Universal LLM Integration**: OpenAI GPT, Google Gemini
|
|
9
|
-
- **Template System**: Jinja2-powered prompt templates with variables
|
|
10
|
-
- **Context Management**: Maintain conversation context across sessions
|
|
11
|
-
|
|
12
|
-
### 🔒 **Enterprise Security**
|
|
13
|
-
- **JWT Authentication**: Secure token-based authentication
|
|
14
|
-
- **Session Management**: Redis-backed secure sessions
|
|
15
|
-
- **CORS Configuration**: Flexible cross-origin resource sharing
|
|
16
|
-
|
|
17
|
-
### 🛠 **Function Calling & Tools**
|
|
18
|
-
- **Native Function Calls**: Direct integration with LLM function calling
|
|
19
|
-
- **Custom Tools**: Build and register custom tools for your chatbot
|
|
20
|
-
- **SQL Query Generation**: Natural language to SQL conversion
|
|
21
|
-
- **API Integrations**: Connect to external services and APIs
|
|
22
|
-
|
|
23
|
-
### 🗄 **Database & Storage**
|
|
24
|
-
- **Multi-Database Support**: PostgreSQL, MySQL, SQLite via SQLAlchemy
|
|
25
|
-
- **Vector Store Integration**: Semantic search and retrieval
|
|
26
|
-
- **Document Processing**: PDF, Word, Excel, and text file handling
|
|
27
|
-
|
|
28
|
-
### 📊 **Analytics & Monitoring**
|
|
29
|
-
- **Query Logging**: Track all LLM interactions
|
|
30
|
-
- **Performance Metrics**: Response times, token usage, costs
|
|
31
|
-
- **Benchmarking**: Compare model performance
|
|
32
|
-
- **Task Management**: Async task processing with status tracking
|
|
33
|
-
|
|
34
|
-
### 🔧 **Developer Experience**
|
|
35
|
-
- **Dependency Injection**: Clean, testable architecture
|
|
36
|
-
- **CLI Tools**: Command-line interface for common tasks
|
|
37
|
-
- **Hot Reloading**: Development-friendly configuration
|
|
38
|
-
- **Comprehensive Logging**: Debug and monitor easily
|
|
39
|
-
|
|
40
|
-
## License
|
|
41
|
-
MIT License
|
|
42
|
-
|
|
43
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|