# Arquitectura del agente logistico

## Objetivo

LightDatai debe ser un agente logistico para operadores, administradores, clientes y choferes. Tiene que entender los circuitos del sistema y consultar datos vivos antes de responder.

No se conecta directo desde el navegador a Ollama/Gemma. El flujo correcto es:

```text
AppChat / modulo UI
  -> AppApi.iaLogisticaPreguntar()
  -> POST /controlador.php { accion:"ia.logistica.preguntar", pregunta, contextoUi }
  -> ControladorIa
      -> valida sesion/perfil
      -> planifica desde la pregunta (global por defecto)
      -> busca docs relevantes via RAG
      -> arma Context Pack operativo
      -> llama Ollama local
      -> devuelve respuesta + fuentes + acciones sugeridas
```

Regla de razonamiento: la pregunta del usuario manda. La ventana activa no limita la consulta; solo aporta contexto cuando el usuario dice "estos", "esta pantalla", "lo que estoy viendo", "filtrados" o "seleccionados". Para datos operativos, el backend planifica y consulta DB antes de pedir redaccion al modelo.

## Capas

### 1. UI

- `base_php/js/core/AppChat.js`: conversacion con Asistente IA.
- `base_php/js/core/AppApi.js`: metodo `iaLogisticaPreguntar`.
- Modulos abiertos pueden aportar `estado()` y seleccion actual.

La UI no decide permisos ni consulta DB directa. Solo manda pregunta y contexto visual opcional.

### 2. Puerta unica

Todo entra por:

```text
POST /controlador.php
```

Accion propuesta:

```text
ia.logistica.preguntar
```

Esto mantiene la auditoria, sesion PHP, hash de sesion y multi-tenant.

### 3. Backend IA

Archivo runtime propuesto:

```text
back/sistema/controlador_ia.php
```

Esta carpeta `back/lightdata_ai/` documenta la arquitectura; el controlador ejecutable vive en `back/sistema/` para respetar el patron actual de controladores.

Responsabilidades:

- validar pregunta;
- conocer usuario, perfil y alcance;
- recuperar documentos relevantes;
- armar contexto operativo;
- llamar al modelo local;
- normalizar la respuesta;
- devolver acciones sugeridas, no ejecutarlas.

### 4. RAG documental

El agente no tiene que memorizar todos los docs. Debe buscar fragmentos relevantes en:

- `manuales_y_circuitos/`
- `docs/`
- `docs/modulos/`
- `docs/DICCIONARIO-DATOS.md`
- `docs/CIRCUITOS-MS.md`
- `docs/MODELO-DATOS.md`
- esta carpeta `back/lightdata_ai/`

### 5. Datos vivos

El agente usa MySQL/Redis/MS segun intencion:

- envio puntual: `ControladorEnvios::obtener`;
- listado/riesgo: `ControladorEnvios::listar`;
- dashboard: `ControladorInformes::dashboard`;
- zonas/clientes/choferes: catalogos;
- GPS/presencia: Redis/WS;
- health: `ControladorHealth`;
- costos/liquidaciones: controladores/procesos existentes.

### 6. Capacidades operativas

El agente no debe razonar con un diccionario de frases. Debe elegir entre capacidades validadas del OS:

- ruta UI (`envios.listado`, `informes.porzonas`, `informes.porcliente`);
- herramienta disponible (`consultarEnvios`, `consultarInforme`);
- controlador backend real (`ControladorEnvios`, `ControladorInformes`);
- tablas fuente (`envios`, `envios_zonas`, `estados_envios`, etc.);
- dimensiones y metricas que puede agrupar.

El catalogo runtime vive en:

```text
back/lightdata_ai/capacidades.php
```

Ejemplo: si el usuario pregunta "pendientes por zonas", el agente debe elegir `informes.porzonas`, no tratar "zona" como texto libre ni inventar una zona. La respuesta se arma con `ControladorInformes::envios(['por' => 'zona'])` y estados reales de `estados_envios`.

### 7. Conocimiento operativo

Antes de elegir una capacidad, el agente necesita entender el circuito y el modelo de datos:

- `envios.estado` es el estado actual;
- `estados_envios` traduce el DID de estado;
- `envios_historial` explica cambios y fecha de estado;
- `envios_direcciones_destino.didEnvioZona` relaciona un envio con `envios_zonas`;
- `clientes.nombre_fantasia` es el nombre operacional del cliente;
- `pendientes` no es un texto: es una regla sobre estados no cerrados.

El conocimiento runtime vive en:

```text
back/lightdata_ai/conocimiento.php
```

Flujo correcto:

```text
lenguaje natural
  -> conocimiento operativo: tablas, campos, relaciones, estados, circuitos
  -> capacidad/herramienta validada
  -> controlador backend real
  -> respuesta con datos vivos
  -> accion UI opcional
```

## Principios

- El agente responde solo con fuentes recuperadas o datos consultados.
- Si falta informacion, debe decirlo.
- Las consultas respetan permisos del perfil.
- Las respuestas deben ser breves, operativas y accionables.
- Las acciones reales requieren confirmacion y backend server-side.
- El contexto enviado al modelo debe ser chico y explicable.

## Flujo de una pregunta

Ejemplo:

```text
"por que no se liquido el envio SEED-CABA-015?"
```

1. Detectar intencion: `explicar_liquidacion` + tracking.
2. Buscar envio por tracking.
3. Traer cabecera, historial, costos, liquidaciones y cliente.
4. Recuperar docs de liquidaciones, costos y estados pagables.
5. Armar contexto.
6. Llamar modelo.
7. Responder con causa probable, evidencia y accion sugerida.

## Salida esperada

```json
{
  "respuesta": "El envio no se liquido porque el movimiento del chofer todavia figura con precioProcesado=0...",
  "intencion": "explicar_liquidacion",
  "fuentes": [
    { "tipo": "db", "nombre": "envios", "did": 123 },
    { "tipo": "doc", "path": "docs/DICCIONARIO-DATOS.md" }
  ],
  "acciones": [
    {
      "tipo": "abrir_modulo",
      "label": "Abrir ficha del envio",
      "payload": { "ruta": "envios.ficha", "opts": { "did": 123 } }
    }
  ]
}
```
