Hermes Agent Cron Upgrade: monitor-mode, notepad y validación preflight

Las tareas programadas son una de las funciones de automatización más prácticas de Hermes Agent: capturar la portada de Hacker News a las 9 de la mañana, comprobar el build cada 30 minutos, resumir tu feed cada hora. Pero cuantos más jobs ejecutas, más evidentes se vuelven los problemas — la mayoría de los ticks queman tokens en pura repetición, un job mal configurado desperdicia una llamada completa al LLM antes de fallar, y pasar estado entre ejecuciones («¿dónde me quedé la última vez?») obliga a improvisar con archivos externos.
El lote que llegó a main a principios de agosto de 2026 dota al cron de tres piezas de equipo críticas:
- monitor-mode — un script o URL barato se ejecuta primero en cada tick; si el hash de su salida no cambia, toda la ejecución del agente se suprime a coste cero de LLM;
- notepad — un scratchpad clave/valor duradero por job que sobrevive entre ejecuciones programadas (cursores, watermarks, watchlists);
- preflight — valida la configuración del job antes de construir cualquier maquinaria del agente; un job roto se marca como
blocked_config, avisa una sola vez y nunca gasta un token.
Además, un logger usage_audit.jsonl que registra honestamente el gasto de tokens de cada ejecución de cron. Este artículo cubre las cuatro novedades, con ejemplos reales de CLI y claves de configuración.
1. monitor-mode: husmear primero, ejecutar solo cuando algo cambia
Por qué existe
El job de monitorización canónico se parece a esto: «cada 5 minutos, comprueba si el feed tiene elementos nuevos y resúmelos si los tiene». Sin monitor-mode, Hermes construye el agente completo y llama al LLM en cada tick — así que pagas por un resultado de «no ha pasado nada» cada vez que el feed está en silencio.
monitor-mode saca la detección de cambios fuera del agente: en cada tick, un script barato (o una petición GET acotada) obtiene la salida de la fuente de monitorización, que se hashea como bytes exactos:
- Hash sin cambios → toda la ejecución del agente se suprime y se registra como un tick silencioso
no_change(sin gasto de LLM, sin entrega); - Hash cambiado → se inyecta en el prompt un bloque
MONITOR CHANGE DETECTED(un diff unificado acotado + la nueva salida) y el agente se ejecuta con normalidad; - El primer tick siempre se ejecuta (establece la línea base);
- Una fuente de monitorización que falla se trata como un error de configuración: el job nunca se salta en silencio.
Uso
Crear desde la CLI:
# Monitor source = a script (resolved relative to ~/.hermes/scripts/, or absolute path)
hermes cron create "every 5m" \
"Summarize any new items on the page" \
--monitor-script feed_watch.sh
# Monitor source = a URL (one bounded GET per tick)
hermes cron create "every 5m" \
"Summarize changes on the status page" \
--monitor-url https://status.example.com/api/health
# Update an existing job
hermes cron edit <job_id> --monitor-script feeds.sh
Desde el chat, a través de la herramienta cronjob:
cronjob(
action="create",
schedule="every 5m",
prompt="Summarize any new items on the page",
monitor_script="feed_watch.sh",
)
Tres restricciones (aplicadas al crear, en el código fuente)
monitor_scriptymonitor_urlson mutuamente excluyentes — una sola fuente de monitorización por job;- el modo monitor es incompatible con
no_agent=True— el objetivo es precisamente suprimir o despertar al agente; los jobs de script puro deben usar el modoscriptnormal; - el script de monitorización debe emitir una salida estable (sin timestamps), o cada hash será distinto y el job se disparará en cada tick.
--monitor-script sigue las mismas reglas de resolución que script: las rutas relativas se resuelven bajo ~/.hermes/scripts/, los .sh/.bash se ejecutan con bash y cualquier otra cosa se ejecuta como Python. La implementación vive en create_job, y el camino de supresión por hash del scheduler, en cron/jobs.py.
2. notepad: estado duradero entre ejecuciones, sin archivos externos
Por qué existe
Los jobs con estado tienen un dolor clásico: el job A ingiere datos a las 2 de la madrugada y el job B procesa «solo lo nuevo» a las 8 — ¿dónde vive el cursor de «lo último visto»? Históricamente lo escribías en un archivo local y gestionabas tú mismo la concurrencia y la limpieza. notepad lo convierte en ciudadano de primera clase: un scratchpad clave/valor duradero por job, guardado en su propia base de datos SQLite (~/.hermes/cron/notepad.db). En cada ejecución, el scheduler vuelca un notepad no vacío dentro del prompt del job — el agente ve el estado dejado por las ejecuciones anteriores y lo actualiza vía CLI durante la ejecución.
Uso
# List the job's notepad (default action)
hermes cron notepad <job_id>
# Read one key
hermes cron notepad <job_id> get cursor
# Write one key
hermes cron notepad <job_id> set cursor 128
# Delete one key
hermes cron notepad <job_id> delete cursor
Es el complemento natural de monitor-mode: tras detectar un cambio, el job escribe «procesado hasta el elemento N» en su notepad, así el siguiente tick sabe exactamente dónde continuar. Hay topes de capacidad — una escritura desmesurada falla de forma ruidosa en lugar de truncarse en silencio:
- 16 KB por valor;
- claves de hasta 128 caracteres;
- 64 KB en total por job.
El camino de lectura inyecta el contenido del notepad en el prompt del job por la misma costura que la salida de context_from; el camino de escritura es el agente en ejecución llamando a hermes cron notepad ... set. Los detalles de implementación están en cron/notepad.py, que sigue el mismo patrón de conexión/pragma que cron/executions.py.
3. preflight: un job roto avisa una sola vez y nunca gasta un token
Por qué existe
La forma más común en que se rompen los jobs de cron no es código malo — es la deriva del entorno: caducó una API key del provider, a una skill adjunta le falta una variable de entorno, las credenciales de entrega quedaron obsoletas. El comportamiento antiguo: el tick se ejecuta, el agente se construye, se llama al LLM, y solo entonces falla — dinero gastado y, a menudo, un error opaco.
preflight valida la configuración del job antes de construir cualquier maquinaria del agente (según el código fuente y la documentación oficial de cron.md):
- la API key del provider se resuelve (se omite cuando está configurada una cadena
fallback_providers, ya que el camino de fallback puede rescatar una clave primaria ausente); - las skills adjuntas están listas (sin variables de entorno, comandos ni archivos de credenciales requeridos que falten);
- los destinos de la plataforma de entrega son conocidos y tienen credenciales de gateway (los destinos
local/originnunca se comprueban).
Ante un fallo:
- el
last_statusdel job pasa a serblocked_config; - se entrega exactamente una alerta (un marcador de deduplicación
preflight_alerted— sin bombardeo por tick), que se limpia al recuperarse para que una futura rotura vuelva a alertar; - cero llamadas al LLM — un job mal configurado nunca gasta tokens.
Activado por defecto vía cron.preflight: true. Para restaurar el comportamiento antiguo:
# config.yaml
cron:
preflight: false
# or on the command line
hermes config set cron.preflight false
Todas las comprobaciones fallan en abierto — un problema de preflight nunca bloquea por sí mismo una ejecución, así que un job sano no se mata por accidente.
4. usage_audit: un libro de contabilidad de tokens para cron
El mismo lote también trajo parte de la mitigación de fugas de tokens del cron: las sesiones de cron ya no lanzan una revisión en segundo plano (skip_background_review), y ahora existe un registro de auditoría del gasto de tokens por disparo en ~/.hermes/cron/usage_audit.jsonl — una línea JSONL por ejecución. Si quieres cuantificar cuánto te ha ahorrado realmente monitor-mode, este archivo es la respuesta.
5. Todo junto: un job de monitorización de cambios barato y consciente
Conectando las tres piezas en un típico job de «monitor de cambios del sitio + resumen incremental»:
# 1) Monitor script: stable output (e.g. the feed's item titles)
cat > ~/.hermes/scripts/feed_watch.sh <<'EOF'
#!/bin/bash
curl -s https://example.com/feed.xml | grep -o '<title>[^<]*</title>'
EOF
chmod +x ~/.hermes/scripts/feed_watch.sh
# 2) Create the monitor job: unchanged hash → silent skip
hermes cron create "every 5m" \
"Summarize new feed items and remember the last seen count in the notepad" \
--monitor-script feed_watch.sh \
--deliver telegram
A partir de ahí: feed sin cambios → tick silencioso no_change, cero tokens; feed cambiado → el agente se despierta, lee el cursor de su notepad, resume los elementos nuevos, actualiza el cursor y entrega a Telegram. Los usuarios que vigilan su presupuesto pueden contrastar usage_audit.jsonl a final de mes.
6. Cuándo NO usar estas funciones
- Los jobs que deben ejecutarse en cada tick (campanadas horarias, heartbeats de mantenimiento) no necesitan monitor-mode — solo añade una comprobación de cambios inútil;
- notepad es por job, no un almacén entre jobs — encadena jobs con
context_fromo almacenamiento externo cuando los datos deben fluir entre tareas; - los jobs de script puro que deben saltarse al agente por completo: usa el
no_agent=True+scriptexistente, no les impongas el modo monitor.
Resumen
Estas tres piezas convierten el cron de un «quemador de dinero programado» en un «despertador bajo demanda»: monitor-mode ahorra (coste cero cuando no cambia nada), notepad recuerda (el estado sobrevive entre ejecuciones), preflight estabiliza (sin quema de tokens con configuración rota, un solo aviso). Para cualquiera que gestione una flota de jobs programados, eso es una reducción real de la factura y una victoria operativa.
¿Nuevo en cron? Empieza con nuestra guía completa de automatización de cron en Hermes Agent; evita que las tareas largas en segundo plano se queden atascadas con la guía de configuración para tareas largas; más consejos de productividad diaria en nuestra colección de consejos de productividad de Hermes Agent. ¿Aún no lo has instalado? La guía de instalación te deja funcionando en cinco minutos.