v0.21.1

Hermes Agent v0.21.1


Overview

v0.21.1 — The Consolidation Release. Publicada el 7 de septiembre de 2026. ~5,139 commits · ~4,364 archivos modificados (+601,014 / −768,419) · ~632 PRs fusionados desde v0.21.0.

Esta ventana no tiene una única función estrella — es una pasada de consolidación, y la historia más grande es invisible: el codebase se descompuso y se adelgazó en ~34 % de sus líneas de código fuente sin ningún cambio de comportamiento (#102117). Alrededor de esa limpieza profunda, el trabajo orientado al usuario se concentra donde los usuarios avanzados lo notan de verdad: la delegación es más rápida y más segura (los resultados llegan en cuanto termina cada subagente y los hijos pueden devolverte los procesos en segundo plano en marcha), los servidores MCP ahora pueden autorizar con device codes en máquinas sin navegador que abrir, los pines de provider OpenRouter pasaron a ser por modelo y los selectores de modelos se refrescan cada 20 minutos, el search_files local ejecuta ripgrep nativo hasta 6× más rápido, la compactación conserva su prefix cache entre reconstrucciones en sesiones de coding, y cron deja de permitir que los ticks silenciosos borren la continuidad mostrándote por fin cuándo un trabajo se disparó tarde.

Esta es una versión de parche: las notas oficiales son breves y la documentación curada completa llega con v0.22.0. Esta página cubre las partes más valiosas de la ventana.


Highlights

1. La limpieza profunda: −34 % de LOC fuente, cero cambios de comportamiento

La historia interna más grande de la ventana es una simplificación de todo el codebase (#102117, fusionado el 4 de septiembre): 1,063,826 → 698,363 líneas de código fuente (−34.4 %). Todos los god files se descompusieron — 37 archivos de más de 5,000 líneas se convirtieron en 6; gateway/run.py pasó de 34,847 a 5,512 líneas y cli.py de 22,426 a 4,656; las funciones de más de 300 líneas bajaron de 192 a 2 y la peor complejidad ciclomática, de 1,075 a 84. Los archivos antiguos siguen existiendo como entry points públicos delgados y el comportamiento no cambia: los JSON schemas de las herramientas, el texto del system prompt, los valores por defecto de configuración y los formatos de red son byte-idénticos, verificado con ejecuciones de paridad del conjunto completo. Lo que obtienes como usuario es un codebase más barato de navegar para un agente, más rápido de cargar y más fácil de mantener — sin cambios de configuración ni de comandos por tu parte.

2. delegate_task: los resultados llegan en cuanto termina cada hijo

Los fan-outs en segundo plano ya no esperan al subagente más lento. delegate_task ahora devuelve el resultado de cada tarea por su cuenta, en cuanto esa tarea se completa, y las tareas que comparten una cadena group opcional por tarea se devuelven juntas como un solo mensaje (#104299):

{
  "tasks": [
    { "goal": "check api latency", "group": "bench" },
    { "goal": "check db latency",  "group": "bench" },
    { "goal": "scan the changelog" }
  ]
}

Las dos tareas bench se informan en un único mensaje agrupado; el escaneo del changelog aterriza solo en cuanto termina — se acabó esperar horas a que un hijo atascado impida ver los demás resultados. Las tareas sin agrupar ocupan cada una su propia unidad, pero toda la llamada sigue contando como una sola plaza contra delegation.max_concurrent_children.

3. Los hijos devuelven al padre los procesos en marcha

Un subagente ahora puede transferirte un proceso en segundo plano de larga duración antes de salir: process_manage(action="handoff", session_id=<id>, data="<purpose>") transfiere la propiedad al padre, y el aviso de finalización aterriza en tu chat con el propósito adjunto (#105125). Todo lo que un hijo deje atrás se notifica explícitamente como terminado en el aviso de delegación del padre en lugar de matarse en silencio, y al hijo se le dice de entrada que su notify=true no es una promesa — se acabaron los orquestadores esperando horas una finalización que nunca puede llegar.

4. Logins MCP sin navegador: device codes

Los servidores MCP que soportan RFC 8628 ahora pueden autorizar desde una terminal sin ningún listener de callback de navegador (#104891) — el flujo que antes te obligaba a usar una máquina con navegador ahora funciona en cualquier host headless:

hermes mcp login <server> --flow device

Hermes descubre el device endpoint anunciado por el servidor, imprime la URI de verificación y el user code, y hace polling hasta que apruebas desde cualquier dispositivo. oauth.flow: device en la configuración de tu servidor MCP convierte el device flow en el valor por defecto para el login y la re-autenticación (el PKCE de navegador sigue siendo el valor por defecto general; --flow browser anula la configuración para un solo login). Las autorizaciones denegadas o caducadas nunca reemplazan las credenciales existentes.

5. Pines OpenRouter por modelo + selectores que se mantienen frescos

provider_routing.models.<model-id> ahora fija un conjunto de providers OpenRouter distinto por modelo, de modo que las reglas de routing ya no pueden enviar en silencio un modelo a un provider que no elegiste (#104159):

provider_routing:
  sort: price
  models:
    "openai/gpt-6-astra":         { only: [openai] }
    "anthropic/claude-fable-5.1": { only: [anthropic] }

La entrada por modelo se aplica en el único punto de estrangulamiento por el que ya pasa toda ruta de petición, así que la CLI, el gateway, el escritorio, cron, /model y los hijos delegados la respetan. Mientras tanto, el selector /model dejó de quedarse obsoleto: los catálogos ahora se refrescan cada 20 minutos (antes con un TTL de 1 hora) y un bucle en segundo plano del gateway los mantiene calientes aunque nadie abra el selector (#101319). El provider de Meta Model API ahora trata su respuesta en vivo /v1/models como el catálogo autoritativo, excluyendo los prefijos que no son de chat como muse-image-* y muse-voice-* (#101503).

6. Las operaciones locales de archivo y búsqueda, mucho más rápidas

search_files en un host POSIX local ahora ejecuta ripgrep como subproceso directo en lugar de dos spawns de bash por llamada (#104502): las búsquedas de contenido bajan de ~85 ms a ~15 ms y las de nombres de archivo, de ~73 ms a ~12 ms (5–6× menos latencia de herramienta con resultados idénticos; HERMES_NATIVE_FILE_READ=0 restaura la vía del shell). Dos victorias complementarias mantienen bajas las facturas de tokens en sesiones de coding largas: las reconstrucciones de compactación ahora fijan la snapshot del workspace de coding por sesión en lugar de volver a sondear git status cada vez, manteniendo intacto el prefix cache del prompt a través de los límites de compactación (#104455); y los subagentes que terminan liberan sus transcriptos del heap del padre, con el contenido de subagentes excluido del índice FTS de trigramas (schema v30) — una ejecución de 1,320 hijos dejaba antes un heap del padre de 1.9 GB y 1 GB de shadow tables (#102032).

Improvements

  • Arranque: hermes serve — el comando que el escritorio lanza en cada arranque en frío — despacha a través de un parser ligero independiente y se salta la construcción del árbol argparse de ~40 subcomandos (cae al parser completo para la ayuda, los flags desconocidos y el routing de contenedores) (#101265).
  • Visibilidad de cron: hermes cron list ahora imprime una línea Dispatch: por trabajo y hermes cron status añade un aviso de trabajos atrasados, de modo que una ejecución de recuperación tras un disparo omitido muestra ⚠ catch-up after missed fire en lugar de hacerse pasar por un éxito puntual (#100445).
  • Configuración de delegación: un hijo delegado fijado a un provider/modelo ya no se redirige en silencio por la cadena de fallback del padre cuando algo falla; delegation.fallback_providers da a los hijos su propia cadena ([] la desactiva y, sin pin, ausente equivale a heredarla) (#105347). Los hijos tampoco heredan ya el tier de prompt cache de 1 hora del padre — los subagentes escriben en el tier de 5 minutos que de verdad usan, evitando un precio 2× de escritura de caché por una retención que nunca cobran (#104168).
  • Higiene de tokens: write_file ahora avisa cuando una reescritura completa del archivo reenvía en su mayoría lo que ya está en disco (≥20k caracteres, ≥80 % de líneas sin cambios), orientando al agente hacia patch para las ediciones pequeñas — 661 escrituras así (~24.9M caracteres, ≈$155 de tokens de salida) se detectaron en una sola ejecución de refactor (#103551).
  • Escritorio: las marcas de tiempo de los transcriptos vuelven a ser legibles en ambos temas, y un nuevo control deslizante Message Bubble (Settings → Appearance) ajusta la opacidad de tus burbujas, de sólida a solo contorno (#103146).

Fixes

  • Las reglas approvals.deny ahora se aplican dentro de los sandboxes aislados de Docker/cloud — antes se saltaban la vía rápida del contenedor, así que una lista de denegaciones podía eludirse con un shell en sandbox incluso bajo --yolo o approvals.mode: off; hermes approvals test refleja el orden corregido (#103649).
  • Cron: los ticks silenciosos de monitor/script-gate ya no reemplazan el contexto de continuidad útil con un stub vacío — la selección de salida recorre los archivos del más nuevo al más antiguo y se salta los documentos vacíos o silenciosos, manteniendo los documentos de error elegibles para la recuperación (#104877). Los almacenes de incidencias y notepad de cron también sobreviven a las actualizaciones que dejan en caché un módulo de ejecución antiguo (#104939).

Upgrade

hermes update

Tras actualizar, ejecuta hermes doctor para verificar la instalación y reinicia el gateway (hermes gateway) para que los cambios de plataforma surtan efecto. El refactor estructural mantiene cada entry point público en su sitio, así que los plugins y configuraciones de terceros se conservan sin cambios. Para ver qué tocará la próxima actualización antes de ejecutarla: hermes update --plan.

← Hermes Agent Changelog