Merge branch 'main' into feature/flow-engine-implementation-15654864159042246464

This commit is contained in:
Marco Gallegos
2025-12-21 02:10:12 -06:00
committed by GitHub
3 changed files with 58 additions and 29 deletions

View File

@@ -19,7 +19,37 @@ La funcionalidad del bot se basa en dos pilares:
--- ---
## 🛠️ Arquitectura Técnica Simplificada ## 📋 Flujos de Trabajo Modulares (Features)
El comportamiento del bot se define a través de **flujos de conversación modulares** gestionados por un motor central (`flow_engine.py`). Cada flujo es un archivo `.json` independiente ubicado en `talia_bot/data/flows/`, lo que permite modificar o crear nuevas conversaciones sin alterar el código principal.
### 1. 👑 Gestión Admin (Proyectos & Identidad)
* **Proyectos (Vikunja)**:
* Resumen inteligente de estatus de proyectos.
* Comandos naturales: *"Marca el proyecto de web como terminado y comenta que se envió factura"*.
* **Wizard de Identidad (NFC)**:
* Flujo paso a paso para dar de alta colaboradores.
* Genera JSON de registro y String Base64 listo para escribir en Tags NFC.
* Inputs: Nombre, ID Empleado, Sucursal (Botones), Telegram ID.
### 2. 👷 Gestión Crew (Agenda & Tareas)
* **Solicitud de Tiempo (Wizard)**:
* Solicita espacios de 1 a 4 horas.
* **Reglas de Negocio**:
* No permite fechas > 3 meses a futuro.
* **Gatekeeper**: Verifica Google Calendar. Si hay evento "Privado" del Admin, rechaza automáticamente.
* **Modo Buzón (Vikunja)**:
* Crea tareas asignadas al Admin.
* **Privacidad**: Solo pueden consultar el estatus de tareas creadas por ellos mismos.
### 3. 🖨️ Sistema de Impresión Remota (Print Loop)
* Permite enviar archivos desde Telegram a la impresora física de la oficina.
* **Envío (SMTP)**: El bot envía el documento a un correo designado.
* **Tracking**: El asunto del correo lleva un hash único: `PJ:{uuid}#TID:{telegram_id}`.
* **Confirmación (IMAP Listener)**: Un proceso en background escucha la respuesta de la impresora y notifica al usuario en Telegram.
El sistema opera con el siguiente flujo: El sistema opera con el siguiente flujo:
@@ -85,13 +115,11 @@ GOOGLE_SERVICE_ACCOUNT_FILE=./google_key.json
* **Credenciales de Google**: Coloca tu archivo de credenciales de la cuenta de servicio de Google Cloud en el directorio raíz del proyecto y renómbralo a `google_key.json`. **El archivo `.gitignore` ya está configurado para ignorar este archivo y proteger tus claves.** * **Credenciales de Google**: Coloca tu archivo de credenciales de la cuenta de servicio de Google Cloud en el directorio raíz del proyecto y renómbralo a `google_key.json`. **El archivo `.gitignore` ya está configurado para ignorar este archivo y proteger tus claves.**
* **Flujos de Conversación**: Para modificar o añadir flujos, edita los archivos JSON en `talia_bot/data/flows/`. * **Flujos de Conversación**: Para modificar o añadir flujos, edita los archivos JSON en `talia_bot/data/flows/`.
### 4. Ejecución con Docker Asegúrate de tener los archivos y directorios base en `talia_bot/data/`:
* `servicios.json`: Catálogo de servicios para el RAG de ventas.
La forma más sencilla de levantar el bot es usando Docker Compose: * `credentials.json`: Credenciales de Google Cloud.
* `users.db`: Base de datos SQLite que almacena los roles de los usuarios.
```bash * `flows/`: Directorio que contiene las definiciones de los flujos de conversación en formato JSON. Cada archivo representa una conversación completa para un rol específico.
docker-compose up --build
```
--- ---
@@ -107,25 +135,26 @@ talia_bot/
├── google_key.json # (Local) Credenciales de Google Cloud ├── google_key.json # (Local) Credenciales de Google Cloud
├── requirements.txt # Dependencias de Python ├── requirements.txt # Dependencias de Python
├── talia_bot/ ├── talia_bot/
│ ├── __init__.py │ ├── main.py # Entry Point y dispatcher principal
│ ├── main.py # Entry point, dispatcher y handlers de Telegram │ ├── db.py # Gestión de la base de datos SQLite
│ ├── db.py # Lógica de la base de datos SQLite │ ├── config.py # Carga de variables de entorno
│ ├── config.py # Carga y validación de variables de entorno │ ├── modules/
│ ├── scheduler.py # (Futuro) Tareas programadas │ ├── flow_engine.py # Motor de flujos de conversación (lee los JSON)
│ ├── webhook_client.py # (Futuro) Cliente para webhooks externos │ ├── identity.py # Lógica de Roles y Permisos
│ ├── data/ │ ├── llm_engine.py # Cliente OpenAI/Gemini
│ │ ├── flows/ # Directorio con flujos de conversación en JSON │ │ ├── vikunja.py # API Manager para Tareas
│ │ ├── services.json # Base de conocimiento para ventas │ │ ├── calendar.py # Google Calendar Logic & Rules
│ │ ── users.db # Base de datos de usuarios │ │ ── printer.py # SMTP/IMAP Loop
│ └── modules/ │ └── sales_rag.py # Lógica de Ventas y Servicios
├── __init__.py └── data/
│ ├── flow_engine.py # Motor que interpreta los flujos JSON │ ├── flows/ # Directorio con los flujos de conversación en JSON
│ ├── calendar.py # Integración con Google Calendar API │ ├── servicios.json # Base de conocimiento para ventas
│ ├── vikunja.py # Integración con Vikunja API │ ├── credentials.json # Credenciales de Google
── onboarding.py # Lógica para el alta de nuevos usuarios ── users.db # Base de datos de usuarios
│ ├── llm_engine.py # (Opcional) Cliente para OpenAI/Gemini ├── .env.example # Plantilla de variables de entorno
│ └── ... (otros módulos) ├── requirements.txt # Dependencias
── ... ── Dockerfile # Configuración del contenedor
└── docker-compose.yml # Orquestador de Docker
``` ```
--- ---

View File

@@ -7,7 +7,7 @@ from talia_bot.config import OPENAI_API_KEY, OPENAI_MODEL
def get_smart_response(prompt): def get_smart_response(prompt):
""" """
Genera una respuesta inteligente usando la API de OpenAI. Genera una respuesta inteligente usando la API de OpenAI.
Parámetros: Parámetros:
- prompt: El texto o pregunta que le enviamos a la IA. - prompt: El texto o pregunta que le enviamos a la IA.
""" """

View File

@@ -44,7 +44,7 @@ def get_tasks():
if not tasks: if not tasks:
return "No tienes tareas pendientes en Vikunja." return "No tienes tareas pendientes en Vikunja."
text = "📋 *Tus Tareas en Vikunja*\n\n" text = "📋 *Tus Tareas en Vikunja*\n\n"
for task in sorted(tasks, key=lambda t: t.get('id', 0))[:10]: for task in sorted(tasks, key=lambda t: t.get('id', 0))[:10]:
status = "" if task.get('done') else "" status = "" if task.get('done') else ""