Agente · dev-cns
Agente · dev-cns
Propósito
Desarrollo y mantenimiento del sistema CNS (CreaRack Network Sentinel) y Edge Intelligence.
Cubre la app monitoring/ (módulos CNS), los servicios AI, el ITSM y la integración con el Agent.
Módulos JS (CNS)
static/js/
├── pages/observatory/
│ ├── ObservatoryCNS.js # Pestaña CNS — thin wrapper de ScopedInsightTab
│ └── ObservatoryCNSHistory.js # Modal Acknowledge History
├── utils/
│ ├── InsightDetailModal.js # Modal compartido (Observatory + Rack Editor + Wireless)
│ ├── InsightUtils.js # Colores, helpers
│ └── InsightActions.js # handleExplain, buildActions
└── services/
├── ScopedInsightTab.js # Servicio centralizado — tab CNS reutilizable
└── InsightIndicatorService.js # Dots pulsantes en sidebars
App Django: monitoring/ (módulos CNS)
monitoring/
├── models_insight.py # AIInsight + AIInsightAuditLog + InsightConversation
├── api/
│ ├── insights.py # Endpoints principales (342 LOC)
│ ├── insight_execution.py # Apply/dry-run/rollback/result (221 LOC)
│ └── insight_schemas.py # Schemas API (189 LOC)
└── services/
├── insight_service.py # Orquestador principal (379 LOC)
├── explain_service.py # Explain + Revise AI calls (64 LOC)
├── command_validation.py # Vendor command whitelists (88 LOC)
├── ai_guardrails.py # Topic filter para Network Tutor
└── ai_providers/
├── base.py # Interfaz base
├── gemini_provider.py # Gemini 3 Flash
├── claude_provider.py # Claude Haiku
└── static_provider.py # Reglas heurísticas (fallback)
Flujo completo Detect → Diagnose → Act → Learn
1. Agent (Sentinel Primary) detecta anomalía
↓
2. POST /api/sentinel/insights/receive
↓
3. SaaS procesa:
· Verifica maintenance window (suprime si activa)
· Verifica rate limits (5/device/h · 100/tenant/h)
· Llama AI provider (Gemini → Claude → Static fallback)
· Crea AIInsight en DB + audit log
· Calcula SLA deadlines (ITSM)
· Busca known issues + runbooks
· Correlaciona con incidents existentes
· Envía notificaciones (webhook/email/Slack/Teams)
· Broadcast WebSocket → Observatory
↓
4. Operador ve: toast + tabla CNS + dot pulsante + badge Rack Editor
↓
5. Operador interactúa (InsightDetailModal):
· Explain → pregunta contextual al AI (persiste en DB)
· Revise → AI re-evalúa con contexto de conversaciones
· Apply Fix → comandos SSH via Agent (whitelist validado)
· Acknowledge → cierra con notas
↓
6. Agent ejecuta comandos via Scrapli SSH
POST /api/sentinel/insights/{id}/result → APPLIED o FAILED
↓
7. Auto-resolve: si device se recupera →
POST /api/sentinel/insights/recover/{target_id}
→ Insights de conectividad se auto-acknowledgen
AI Providers
Configuración
# config/settings/base.py
EDGE_AI_PROVIDER = env("EDGE_AI_PROVIDER", default="gemini") # gemini | claude
GEMINI_API_KEY = env("GEMINI_API_KEY", default="")
ANTHROPIC_API_KEY = env("ANTHROPIC_API_KEY", default="")
Proveedores y modelos
| Provider | Modelo | Uso | Temperatura |
|---|
| Gemini | gemini-3-flash-preview | Principal | 0.2 |
| Claude | claude-haiku-4-5-20251001 | Alternativo | 0.2-0.3 |
| Static | Reglas heurísticas | Fallback automático | N/A |
Fallback automático
Gemini falla (429/timeout) → 3 reintentos con backoff exponencial (2s→4s→8s) → Static Rules.
Static Rules cubre 6 patrones: CRC errors, packet loss, interface down, bandwidth saturation, latency spike, client drop.
Parámetros AI
| Parámetro | Valor |
|---|
| Max tokens (diagnóstico) | 16384 |
| Max tokens (explain) | 512 |
| Max tokens (revise) | 768 |
Modelo AIInsight
Ciclo de vida
PENDING → EXECUTING → APPLIED
↘ ACKNOWLEDGED ↗ FAILED
↘ EXPIRED (4h automático)
Campos principales
| Campo | Tipo | Descripción |
|---|
incident_id | UUID | Identificador único universal |
case_id | str | CNS-000042 (auto-increment por org) |
summary | str(200) | Resumen del diagnóstico AI |
root_cause | text | Causa raíz identificada |
confidence_score | float | 0.0 - 1.0 |
osi_layer | int | Capa OSI afectada (1-7) |
risk_level | str | HIGH / MEDIUM / LOW |
commands | JSON list | Comandos SSH recomendados |
rollback_commands | JSON list | Comandos de rollback |
ai_provider | str | gemini / claude / static |
expires_at | datetime | +4h desde creación |
is_revised | bool | Si fue re-evaluado |
original_summary | str | Summary antes de revisión |
original_root_cause | text | Root cause antes de revisión |
Risk levels
| Nivel | Color CSS | Criterios |
|---|
| HIGH | #ef4444 | 100% packet loss, device unreachable, security threats |
| MEDIUM | #f59e0b | >30% loss, bandwidth saturation, interface down |
| LOW | #3b82f6 | Anomalías menores, degradación leve |
Umbrales de detección (Agent Sentinel)
| Anomalía | Umbral | Loop origen |
|---|
| Packet loss | >10% | ping_loop |
| Latency | >200ms | ping_loop |
| CRC errors | >100/min | snmp_bandwidth_loop |
| Client drop | >30% | snmp_extras |
| Interface down | Estado = down | snmp_bandwidth_loop |
| Bandwidth saturation | >90% | snmp_bandwidth_loop |
Command Whitelist (seguridad)
Comandos siempre permitidos
show, display, get, ping, traceroute, dir, more
Comandos siempre bloqueados
reload, reboot, erase, format, delete, write erase,
copy running-config startup-config, configure replace
| Vendor | Comandos adicionales permitidos |
|---|
| Cisco IOS | clear counters, clear arp-cache, interface, no shutdown |
| NX-OS | clear counters, interface, system mode maintenance |
| Arista EOS | clear counters, interface, ip route |
| Juniper JunOS | clear interfaces statistics, set interfaces, commit |
API Endpoints (18 total)
Insights
| Método | Endpoint | Descripción |
|---|
| POST | /api/sentinel/insights/receive | Recibir anomalía del Agent |
| GET | /api/sentinel/insights/ | Listar (filtros: target_ids, status, risk, search, dates) |
| GET | /api/sentinel/insights/{id}/ | Detalle completo |
| GET | /api/sentinel/insights/stats/ | Stats por status (acepta target_ids) |
| GET | /api/sentinel/insights/stats/providers/ | Stats por AI provider |
Acciones
| Método | Endpoint | Descripción |
|---|
| POST | /api/sentinel/insights/{id}/acknowledge | Acknowledge con notas |
| POST | /api/sentinel/insights/{id}/explain | Pregunta contextual al AI |
| GET | /api/sentinel/insights/{id}/conversations | Historial Q&A |
| POST | /api/sentinel/insights/{id}/revise | Re-evaluar diagnóstico |
| POST | /api/sentinel/insights/{id}/apply | Aplicar fix via Agent |
| POST | /api/sentinel/insights/{id}/dry-run | Validar sin ejecutar |
| POST | /api/sentinel/insights/{id}/rollback | Ejecutar rollback |
| POST | /api/sentinel/insights/{id}/result | Agent reporta resultado |
| POST | /api/sentinel/insights/recover/{target_id} | Agent reporta recovery |
| DELETE | /api/sentinel/insights/purge | Purgar todos (superuser) |
Network Tutor
| Método | Endpoint | Descripción |
|---|
| POST | /api/sentinel/tutor/ask | Preguntar (con device context opcional) |
| GET | /api/sentinel/tutor/history | Historial (50 msgs, TTL 4h, Valkey) |
| POST | /api/sentinel/tutor/clear | Limpiar historial |
Filtrado por target_ids
Los endpoints stats y list aceptan target_ids (comma-separated) para scope por página:
GET /api/sentinel/insights/?target_ids=1,2,3&status=pending
GET /api/sentinel/insights/stats/?target_ids=1,2,3
Arquitectura centralizada (v1.0.43+)
ScopedInsightTab
Servicio reutilizable que renderiza una tab CNS completa (stats, filtros, tabla, export CSV, auto-refresh) scoped a un conjunto de targets.
import { ScopedInsightTab } from '../services/ScopedInsightTab.js';
const cns = new ScopedInsightTab({
containerId: 'my-cns-container',
targetIds: [1, 2, 3], // Solo insights de estos targets
actionNamespace: 'wireless', // Prefijo data-action (evita conflictos)
});
cns.render();
InsightIndicatorService
Gestiona dots pulsantes en sidebars. Colores: rojo (HIGH) · naranja (MEDIUM) · azul (LOW).
Soporta actualizaciones en tiempo real via WebSocket insight_update.
DeviceProfile.assigned_page (antes MonitoringTarget.scope)
El campo scope de MonitoringTarget fue eliminado (Ficha Central F4, migración monitoring/0025); la pertenencia a página la decide DeviceProfile.assigned_page (wireless/ups/signage, null = sin asignar). Cada página obtiene sus targets vía las fichas:
profiles = DeviceProfile.objects.filter(organization=org, assigned_page='wireless').select_related(
'linked_monitoring_target'
)
target_ids = [p.linked_monitoring_target_id for p in profiles if p.linked_monitoring_target_id]
Páginas con CNS integrado
| Página | assigned_page | Namespace |
|---|
| Observatory | — (fleet-wide, sin filtro) | observatory |
| Wireless | wireless | wireless |
| UPS | ups | ups |
Patrón para añadir CNS a nueva página
- Backend: añadir el choice a
DeviceProfile.assigned_page y asignar assigned_page='nueva_pagina' a las fichas
- View: pasar
target_ids al template context
- Template: añadir tab header “CNS” + container div vacío
- JS: instanciar
ScopedInsightTab con containerId, targetIds, actionNamespace único
- JS: instanciar
InsightIndicatorService para dots del sidebar
- WS handler: en
insight_update → cnsTab.refresh() + indicators.update()
- ITSM: botón “ITSM Settings” →
/monitoring/observatory/?tab=itsm
WebSocket events
{
"type": "insight_update",
"data": {
"insight_id": 42,
"summary": "Packet loss detected on GigabitEthernet0/1",
"risk_level": "HIGH",
"target_name": "switch-core-01",
"status": "pending",
"timestamp": "2026-03-10T14:30:00Z"
}
}
Efectos: toast notification + refresh tabla CNS + dot pulsante en sidebar + badge Rack Editor.
Network Tutor
- Guardrails de 2 capas: pre-filtro ~130 términos de networking + system prompt
- Contexto de dispositivo inyectado si hay device seleccionado
- Historial: 50 msgs · TTL 4h · almacenado en Valkey
Auto-Resolve
Solo se auto-resuelven insights cuyo summary/anomaly_trigger contenga:
"total loss" · "unreachable" · "100%" · "device down"
Insights de CRC, latencia, bandwidth → require acknowledge manual.
Rate Limiting
| Nivel | Límite |
|---|
| SaaS per device | 5 insights/hora |
| SaaS per tenant | 100 insights/hora |
| Agent cooldown por anomalía/target | 5 minutos |
| Agent global | 10 insights/hora |
Reset desde UI: Agent Fleet Manager → Actions → Reset.
Reset via API: POST http://localhost:5050/sentinel/reset
Administración en producción
# Purgar todos los insights via CLI
ssh root@crearack.com "docker exec crearack-pro-zcmvsl-web-1 python manage.py shell -c `
\"from django.db import connection; cursor = connection.cursor(); `
[cursor.execute(f'DELETE FROM {t}') or print(f'{t}: {cursor.rowcount}') `
for t in ['monitoring_notificationlog','monitoring_insightconversation', `
'monitoring_aiinsightauditlog','monitoring_insightlink','monitoring_aiinsight']]\""
Convenciones y restricciones
- Modelo Gemini fijo:
gemini-3-flash-preview · Claude fijo: claude-haiku-4-5-20251001
- Nunca ejecutar comandos sin validar contra
command_validation.py
ScopedInsightTab es el patrón estándar para nuevas integraciones — no reimplementar tab CNS desde cero
InsightIndicatorService centraliza todos los dots del sidebar — no duplicar lógica
- Audit log obligatorio para toda acción sobre un insight (
AIInsightAuditLog)
- Los insights se auto-expiran a las 4h — diseñar UI asumiendo esto
Véase también
- [[concept—monitoring—cns]]
- [[concept—monitoring—itsm]]
- [[crearack—monitoring—cns-sentinel]]
- [[crearack-tech—guides—cns-guide]]
- [[crearack-tech—guides—itsm-guide]]
- [[crearack-tech—guides—cns-itsm-user-guide]]
- [[crearack-tech—architecture—sentinel-mode]]
- [[crearack-tech—backend—network-observatory]]
- [[crearack-tech—guides—gemini-api-setup]]