# Telemetría Volkom Mesh — Guía para usuarios

Esta guía explica, en lenguaje claro, **cómo un agente le manda telemetría a
Volkom Mesh**. Hay dos canales independientes:

1. **Ejecución** (lo que el agente *hizo*): arranque, pasos, fin, errores, tiempos.
2. **Negocio** (los *KPIs* del cliente): plata, cantidades, porcentajes, tiempos
   que importan al negocio (ventas, facturas, clientes atendidos, etc.).

Los dos canales viven en **la misma API** y se guardan en **una sola base de
datos** por tenant. Tanto el portal del cliente (volkommesh) como el panel de
Volkom (adminvm) leen exactamente lo mismo de ahí.

---

## Conceptos en 1 minuto

| Concepto | Qué es |
|----------|--------|
| **Tenant** | El cliente (ej. `shopflow`). Tiene su propia base de datos aislada. |
| **Agente** | Un programa que hace una tarea (ej. `sales-monitor`). |
| **Corrida (run)** | Una ejecución del agente, identificada por un `run_id` único. |
| **Evento** | Cada cosa que pasa en una corrida: arrancó, hizo un paso, terminó. |
| **KPI** | Un número de negocio que el agente reporta (ventas, % de éxito…). |
| **Token** | La credencial (Bearer) con la que el agente se autentica. |

> **La regla de oro:** una corrida es una secuencia de eventos que comparten el
> mismo `run_id`. Empieza con un evento `started`, puede tener varios `in_progress`
> (los pasos), y cierra con `completed` o `failed`.

---

## Canal 1 — Telemetría de EJECUCIÓN

Cuenta la historia de lo que hizo el agente. Cada evento puede llevar tantos
detalles como quieras — desde algo mínimo hasta una narrativa rica paso a paso.

### Las dimensiones de un evento

Todas son **opcionales** salvo las básicas. Llená lo que tenga sentido para tu agente:

| Dimensión | Para qué sirve | Ejemplo |
|-----------|----------------|---------|
| `message` | Descripción humana del paso | "Descargó el adjunto del correo" |
| `level` | Importancia/color | `info`, `warning`, `error`, `success`, `debug` |
| `category` | Agrupa los pasos por fase | "Correo", "Procesamiento", "Cierre" |
| `metrics` | Números medibles (graficables) | `{"emails": 11, "filas": 1240}` |
| `links` | Referencias externas | URL de un documento, una orden, un dashboard |
| `source` | Origen técnico | `email_skills.py:474` |
| `seq` | Orden del paso dentro de la corrida | 1, 2, 3… |

> **Principio rector:** el front es **genérico**. Muestra lo que mandes, sin
> código a medida. Si agregás un KPI o una categoría nueva, aparece sola — no hay
> que tocar la interfaz.

### Cómo se ve una corrida típica

```
▸ started                                        (arranca la corrida)
  · Buscó correos        cat: Correo         {emails: 11}
  · Descargó adjunto     cat: Correo
  ⚠ Reintento de parseo  cat: Procesamiento  level: warning
  · Consolidó datos      cat: Procesamiento  {clientes: 15}
  · Subió a Drive        cat: Cierre         link: https://drive…
■ completed                                      (cierra OK)
```

---

## Canal 2 — Telemetría de NEGOCIO (KPIs)

Aparte de *qué hizo*, el agente puede reportar **cuánto valió** para el negocio.
Esto alimenta el dashboard ejecutivo (tarjetas, tendencias, comparativas).

### Un KPI se define con 4 cosas

| Campo | Qué es | Ejemplo |
|-------|--------|---------|
| `key` | Identificador interno | `revenue` |
| `label` | Nombre visible | "Facturación" |
| `unit` | Cómo se formatea | ver tabla abajo |
| `agg` | Cómo se totaliza en un período | ver tabla abajo |

### Unidades disponibles (`unit`)

| Unidad | Se muestra como | Ejemplo |
|--------|-----------------|---------|
| `count` | número | 1.240 |
| `money:<ISO>` | moneda | `money:USD` → US$ 9.500 · `money:ARS` → $ 1.200.000 |
| `percent` | porcentaje | 3,4 % |
| `duration` | tiempo (el valor se da en segundos) | 2 h 15 min |

### Agregaciones disponibles (`agg`) — cómo se suma en el período elegido

| Agg | Qué hace | Usar para |
|-----|----------|-----------|
| `sum` | suma todo | ventas, facturas, unidades |
| `last` | toma el último valor | stock actual, MRR, % de ocupación |
| `avg` | promedio | tiempo de espera promedio |
| `max` | el máximo | pico de uso |

> **Por qué importa el `agg`:** si reportás "ventas = 100" en 30 corridas y la
> unidad es `sum`, el período muestra 3.000. Si fuera `last` (ej. stock), mostraría
> solo el último: 100. Elegir mal el `agg` da números equivocados en el dashboard.

---

## Las dos formas de mandar telemetría

### Forma A — Con el carcass (recomendado, agentes en Python)

Si tu agente usa `volkom-core`, **no tocás HTTP**: heredás de `BaseAgent` y usás
métodos. El carcass arma los eventos, los manda y maneja el ciclo de la corrida.

```python
from volkom_core import BaseAgent, AgentResult, KPI

class SalesMonitor(BaseAgent):
    agent_name = "sales-monitor"
    agent_version = "1.0.0"
    description = "Monitorea ventas diarias."
    # KPIs de negocio que este agente reporta:
    business_kpis = [
        KPI("orders",  "Pedidos",      "count",     "sum"),
        KPI("revenue", "Facturación",  "money:USD", "sum"),
    ]

    def run(self) -> AgentResult:
        # --- Telemetría de EJECUCIÓN (pasos) ---
        self.event("Conectó a la tienda", category="Ingesta")
        self.event("Leyó pedidos", category="Ingesta", metrics={"pedidos": 42})
        self.warn("3 pedidos sin dirección", category="Validación",
                  metrics={"incompletos": 3})

        # --- Telemetría de NEGOCIO (KPIs) ---
        self.kpi("orders", 42)
        self.kpi("revenue", 9500)

        return AgentResult(records_processed=42)
```

El `started`, el `completed`/`failed`, los tiempos y el `run_id` los pone el
carcass solo cuando corre el agente. Vos solo describís lo que pasa.

**Métodos del carcass:**
- `self.event(message, level=, category=, metrics=, links=, source=)` — un evento rico.
- `self.step(msg)` / `self.info(msg)` / `self.warn(msg)` / `self.error(msg)` — atajos por nivel.
- `self.kpi(key, value)` — reporta un KPI de negocio (debe estar declarado en `business_kpis`).
- `self.emit_metric(key, value)` — metadata libre en el evento de cierre (no es KPI graficable).

### Forma B — HTTP directo (cualquier lenguaje)

Si tu agente no es Python o querés controlar el HTTP, pegás a la API directamente.
El detalle exacto de endpoints, headers y JSON está en la
**[Referencia de la API](../api/)** (pensada para que la procese Claude Code o un dev).

En resumen, son 3 llamadas:
1. `POST /api/v1/agents/register` — declara el agente y sus KPIs (una vez).
2. `POST /api/v1/telemetry` — un evento de ejecución (uno por started/paso/cierre).
3. `POST /api/v1/telemetry/business` — los KPIs de una corrida.

Todas con el header `Authorization: Bearer <token-del-agente>`.

---

## Errores comunes (y cómo evitarlos)

- **Todos los pasos comparten el `run_id`.** Si cada evento usa un `run_id`
  distinto, el portal los ve como corridas separadas y "se pierde" la narrativa.
- **Cerrá siempre la corrida** con `completed` o `failed`. Una corrida sin cierre
  queda figurando como "en curso" para siempre.
- **Declará los KPIs antes de usarlos** (`business_kpis` / `register`). Si mandás
  un KPI sin declarar, el valor entra pero el dashboard no sabe su unidad/agg.
- **Elegí bien el `agg`.** `sum` para cosas que se acumulan, `last` para estados.
- **El nivel hace al color.** Usá `warning`/`error` para que los problemas se
  resalten en rojo/ámbar en la actividad.

---

## ¿Dónde veo la telemetría?

- **Portal del cliente** (volkommesh): pantalla **Actividad** (corridas agrupadas,
  expandís y ves los pasos) + **Dashboard** de negocio (tarjetas con los KPIs).
- **Panel de Volkom** (adminvm): **Runs** por tenant (misma data, vista técnica)
  + **Audit Log** (quién hizo qué en la plataforma).

Ambos leen la **misma API y la misma base de datos**. Lo que el agente manda una
vez, se ve en los dos lados.
