Sin reinicios: Hermes sirve al instante los perfiles nuevos mientras el gateway sigue en marcha


Son las dos de la mañana y acabas de dejar listo un tercer bot: hermes profile create, pegas el token, escribes hola en Telegram, y no contesta nadie. El escritorio sigue mostrando el gateway de ese perfil como detenido. Buscas en la documentación y la respuesta es «reinicia el gateway». Pero los otros dos perfiles están a mitad de tareas largas, y reiniciar significa interrumpir a los dos.

Esa disyuntiva se acabó. El PR #109239, fusionado en main el 2026-09-12, enseña a un gateway multiplex en ejecución a detectar los perfiles que aparecen por debajo y servirlos de inmediato: sin reiniciar y sin dañar a los perfiles que ya estaban trabajando.

Qué es exactamente un gateway multiplex

Por defecto, un perfil es una configuración independiente más un bot, y mantener ese bot en línea implica ejecutar un proceso de gateway solo para él: hermes -p nombre gateway run. Más perfiles, más procesos: más memoria, más registros y más puertos que vigilar.

Un gateway multiplex lo hace de otra manera: un único proceso de gateway aloja los adaptadores de bot de varios perfiles a la vez. Se activa con gateway.multiplex_profiles: true en la configuración, y a partir de ahí ya no arrancas un proceso por perfil. Todo comparte un gateway, mientras cada perfil conserva su propio entorno aislado: su memoria, su base de datos SQLite y su caché de agentes.

El precio de ese diseño se paga en el descubrimiento. El multiplexor enumeraba el directorio profiles/ exactamente una vez, al arrancar: _start_secondary_profile_adapters construía adaptadores con la lista tal como estaba en ese instante, _record_served_profiles anotaba a quién se estaba sirviendo, y cron reutilizaba la misma instantánea profile_homes. Un perfil creado después de ese momento no aparecía en la lista: sin adaptador, sin sondeos, su bot no podía conectarse nunca y el escritorio informaba que el gateway de ese perfil estaba detenido. Si, en cambio, borrabas un perfil, se quedaba en served_profiles para siempre.

En un mundo de un bot por proceso eso no molesta: un bot nuevo recibe un proceso nuevo. Con multiplexación, en cambio, profiles/ es un directorio que cambia y el gateway lo había mirado una sola vez. Crear un perfil debería significar que funciona, sin pedirte que reinicies todo el gateway —y que interrumpas el trabajo largo de los demás— por un adaptador que nunca llegó a construirse.

Tres situaciones, tres caminos

El PR #109239 (fusionado el 2026-09-12, +641 / −43 en 27 archivos) convierte al multiplexor de «enumerar una vez al arrancar» en «reconciliar de forma continua». El gateway en marcha compara sin parar el directorio profiles/ con el conjunto que ya está sirviendo y actúa según la diferencia. Casi todo cabe en tres situaciones.

Situación Cómo se dispara Qué hace el gateway
Perfil nuevo hermes profile create, el POST /api/profiles del panel, el New profile del escritorio Construye el adaptador y lo sirve de inmediato; además hace ping al socket de control del gateway con un verbo nuevo, rescan-profiles
Credenciales añadidas después Cambia el config.yaml o el .env de un perfil servido El cambio de firma dispara un reescaneo; el adaptador se construye dentro del ámbito de ejecución de ese perfil. Las plataformas ya activas se omiten y los tokens duplicados topan con la misma protección
Perfil borrado Se elimina del directorio profiles/ Desmonta el adaptador, cancela el enrutado y libera los manejadores de pairing / busy / caché de agentes / SQLite / memoria

Creado: se sirve al instante. Las tres vías funcionan. El comando hermes profile create, el POST /api/profiles del panel y el flujo New profile del escritorio hacen ping al socket de control después de crear el perfil, usando el verbo nuevo rescan-profiles para que el gateway mire otra vez ahora y no en la siguiente pasada.

Credenciales después. Crear primero el perfil y pegar después el token del bot es el orden habitual, y esas credenciales cuentan como configuración que apareció tras el arranque. Ese caso se detecta por los cambios de mtime en el config.yaml o el .env del perfil servido: el cambio dispara un reescaneo y el adaptador se construye en el ámbito de ejecución propio de ese perfil. Las plataformas que ya están activas se omiten, y un token duplicado se topa con exactamente la misma protección contra credenciales duplicadas que el arranque usa desde siempre: el segundo queda aparcado con una advertencia y nunca recibe su propio poller, porque dos pollers sobre un mismo token se pelean por los mismos mensajes.

Borrado: se desmonta y pierde la ruta. Se cancelan las reconexiones, se liberan los manejadores de pairing / busy / caché de agentes / SQLite / memoria, desaparecen las rutas /p/nombre/ de ese perfil y served_profiles se actualiza en consecuencia. No queda ningún adaptador a medio morir ocupando memoria ni reteniendo el token del bot.

El reescaneo de respaldo cada 30 segundos

Hacer ping al socket de control es la vía rápida, y las vías rápidas fallan: puede que el gateway esté arrancando, que el socket de control aún no escuche o simplemente que no haya respuesta. Por eso el cambio incluye también un vigilante supervisado que reescanea profiles/ cada 30 segundos (la constante del código es _PROFILE_RESCAN_INTERVAL_SECS = 30.0). Servir al instante es el mejor esfuerzo; la corrección la garantiza la pasada periódica que hay debajo.

El cliente del socket de control es rescan_gateway_profiles(home, timeout=8.0), que envía rescan-profiles y normalmente devuelve un resultado con served_profiles, added, removed y compañía. Lo interesante es la degradación deliberada: si ningún gateway responde, o el que responde es una versión antigua, la llamada devuelve None. Quien la invoca no falla: recurre al reescaneo periódico, que en la CLI significa mantener el recordatorio de reinicio de siempre. En el otro sentido es igual de tolerante: una instalación antigua de Hermes no se cae porque un cliente nuevo le haga una pregunta que no entiende.

Los reescaneos son baratos porque la detección de firmas no recorre el contenido del directorio: mira exactamente dos archivos, config.yaml y .env, y compara su (mtime_ns, size). Son las constantes _PROFILE_SIGNATURE_FILES = ("config.yaml", ".env"). Eso explica también por qué pegar credenciales provoca una reconstrucción: guardas el archivo, el mtime se mueve y la firma cambia. Cualquier otra cosa que cambie alrededor, como un registro nuevo o una caché suelta, no provoca falsos positivos.

La implementación vive en un módulo nuevo, gateway/run_profile_reconcile.py, enganchado al entorno del gateway como GatewayProfileReconcileMixin: se parece más a un reconciliador que vigila el directorio profiles/ que a otra capa de gestión de procesos.

cron, descubrimiento MCP y enrutado de registros vienen incluidos

Un perfil nuevo no es solo un bot más. Los temporizadores de cron pasaron aquí a usar un enumerador vivo, así que las tareas programadas de un perfil recién creado sí se ejecutan, en lugar de quedar descartadas por no figurar en la instantánea del arranque. Los perfiles nuevos también reciben descubrimiento MCP y enrutado de registros. Son esos detalles los que hacen honesta la frase «funciona en cuanto lo creas»; si no, tu bot nuevo respondería mensajes mientras sus propias tareas programadas se quedan sin hacer nada.

Si quieres que cada perfil ejecute cron con su propio bot, la guía de cron por perfil trae el ejemplo completo.

Nada más se interrumpe

La pregunta que merece la pena hacerse sobre el servicio en caliente es si reinicia en silencio a todos los demás de paso. No lo hace. Durante toda la pasada de reconciliación, los demás perfiles servidos quedan totalmente intactos: el mismo pid, los mismos recuentos de sondeo, y las conversaciones en curso no se interrumpen. La reconciliación solo toca la diferencia: añade lo nuevo, desmonta lo que ya no está y deja exactamente igual todo lo que ya era correcto.

Ahí está la diferencia real con reiniciar el gateway. Un reinicio derriba el proceso y todos los adaptadores con él, y los vuelve a construir enteros. La reconciliación cambia solo la parte que hace falta cambiar. Para un gateway multiplex, eso es lo que debería significar la palabra «en caliente».

Lo que verás en la interfaz

La señal más visible es un aviso que deja de aparecer. El endpoint de configuración de plataformas (un PUT a /api/messaging/platforms/ con el id de la plataforma) ahora devuelve un campo hot_served. Cuando vale true, tanto el escritorio (en los seis idiomas) como el panel se saltan el aviso de que hace falta reiniciar.

hermes profile create también confirma el servicio en caliente directamente. Solo conservas el recordatorio de reinicio cuando el multiplexor de verdad no ha recogido el perfil, por ejemplo si no hay ningún gateway en ejecución o si el socket de control no respondió.

Cómo usarlo

  1. Comprueba que la multiplexación está activada: gateway.multiplex_profiles: true.
  2. Crea el perfil: hermes profile create nightshift.
  3. Pon el token del bot en su .env o su config.yaml. Cualquier orden vale; si lo pegas después, el cambio de firma construye el adaptador por ti.
  4. Revisa con hermes gateway status y confirma que el perfil aparece entre los servidos.
  5. Si no aparece: dale al reescaneo de respaldo hasta 30 segundos. Si sigue sin aparecer, hermes gateway restart sigue siendo la salida de emergencia. Un gateway antiguo no conoce el verbo rescan-profiles y en ese caso reiniciar es el único camino, así que primero confirma que tu Hermes es lo bastante nuevo como para incluir este cambio.

En resumen

Este cambio no añade ningún comando nuevo. Cambia cómo reacciona el gateway multiplex a los cambios: enumerar una vez al arrancar pasa a ser reconciliar en marcha. Los perfiles nuevos se sirven al instante, las credenciales tardías reconstruyen el adaptador, los perfiles borrados se desmontan y pierden la ruta, un reescaneo cada 30 segundos cubre los fallos de la vía rápida, y los perfiles que ya se servían no se tocan nunca. Si quieres comprobarlo tú mismo, tests/gateway/test_multiplex_hot_serve.py tiene tres casos que corresponden a los tres caminos: un perfil creado se sirve, unas credenciales añadidas construyen un adaptador y un perfil borrado cancela su enrutado.

Para el panorama general de ejecutar varios perfiles a la vez, mira varios perfiles en una sola máquina; para controlar qué perfiles pueden servir bots, la lista de permitidos de perfiles del gateway entra en más detalle.

Una nota de versión, porque importa: esto llegó a main el 2026-09-12 y forma parte del trabajo posterior a v0.21.2, publicada el 2026-09-11. Todavía no ha salido en ninguna versión etiquetada, así que si lo quieres hoy, quieres main.