Sem reiniciar: o Hermes passa a servir na hora os perfis criados com o gateway em execução

São duas da manhã e você acabou de deixar um terceiro bot pronto: hermes profile create, cola o token, manda um olá no Telegram — e ninguém responde. O desktop continua mostrando o gateway desse perfil como parado. Você procura na documentação e a resposta é reiniciar o gateway. Só que os outros dois perfis estão no meio de tarefas longas, e reiniciar significa interromper os dois.
Esse impasse acabou. O PR #109239, mesclado na main em 2026-09-12, ensina um gateway multiplex em execução a perceber os perfis que surgem embaixo dele e a servi-los imediatamente: sem reiniciar e sem atrapalhar os perfis que já estavam trabalhando.
O que é, de fato, um gateway multiplex
Por padrão, um perfil significa uma configuração independente mais um bot, e manter esse bot no ar exige um processo de gateway só para ele: hermes -p nome gateway run. Mais perfis, mais processos — mais memória, mais logs e mais portas para vigiar.
Um gateway multiplex faz diferente: um único processo de gateway hospeda os adaptadores de bot de vários perfis ao mesmo tempo. Você liga isso com gateway.multiplex_profiles: true na configuração e, depois disso, não sobe mais um processo por perfil. Tudo compartilha um gateway, enquanto cada perfil mantém seu próprio ambiente isolado — sua memória, seu banco SQLite e seu cache de agente.
O preço desse desenho aparece na etapa de descoberta. O multiplexador enumerava o diretório profiles/ exatamente uma vez, na inicialização: _start_secondary_profile_adapters montava os adaptadores a partir da lista como ela estava naquele instante, _record_served_profiles anotava quem estava sendo servido, e o cron reaproveitava o mesmo instantâneo profile_homes. Um perfil criado depois disso não entrava na lista: sem adaptador, sem sondagem, o bot dele nunca conseguia conectar, e o desktop informava que o gateway daquele perfil estava parado. Na direção oposta, um perfil apagado ficava para sempre dentro de served_profiles.
Num mundo de um bot por processo isso não incomoda: bot novo, processo novo. Com multiplexação, porém, profiles/ é um diretório que muda, e o gateway tinha olhado para ele uma única vez. Criar um perfil deveria significar que ele funciona, sem exigir que você reinicie o gateway inteiro — e interrompa o trabalho longo dos outros — por causa de um adaptador que nunca chegou a ser construído.
Três situações, três caminhos
O PR #109239 (mesclado em 2026-09-12, +641 / −43 em 27 arquivos) transforma o multiplexador de “enumerar uma vez na inicialização” em “reconciliar continuamente”. O gateway em execução compara o tempo todo o diretório profiles/ com o conjunto que já está servindo e age conforme a diferença. Três situações cobrem quase tudo.
| Situação | Como começa | O que o gateway faz |
|---|---|---|
| Perfil novo | hermes profile create, o POST /api/profiles do painel, o New profile do desktop |
Monta o adaptador e serve na hora; além disso, faz ping no socket de controle do gateway por um verbo novo, rescan-profiles |
| Credenciais adicionadas depois | O config.yaml ou o .env de um perfil servido muda |
A mudança de assinatura dispara um rescan; o adaptador é montado no escopo de execução daquele perfil. Plataformas que já estão no ar são ignoradas, tokens duplicados caem na mesma proteção |
| Perfil removido | Sai do diretório profiles/ |
Desmonta o adaptador, cancela o roteamento e libera os identificadores de pairing / busy / cache de agente / SQLite / memória |
Criado: servido na hora. Os três caminhos funcionam. O comando hermes profile create, o POST /api/profiles do painel e o fluxo New profile do desktop fazem ping no socket de controle depois de criar o perfil, usando o verbo novo rescan-profiles para que o gateway olhe de novo agora, e não só na próxima passagem.
Credenciais depois. Criar o perfil primeiro e colar o token do bot depois é a ordem mais comum, e essas credenciais contam como configuração que apareceu após a inicialização. Esse caso é capturado por mudanças de mtime no config.yaml ou no .env do perfil servido: a mudança dispara um rescan e o adaptador é montado no escopo de execução próprio daquele perfil. Plataformas que já estão ativas são ignoradas, e um token duplicado esbarra exatamente na mesma proteção contra credenciais duplicadas que a inicialização sempre usou: o segundo fica de lado com um aviso e nunca ganha um poller próprio, porque dois pollers no mesmo token de bot brigam pelas mesmas mensagens.
Removido: desmontado e fora do roteamento. As reconexões são canceladas, os identificadores de pairing / busy / cache de agente / SQLite / memória são liberados, os caminhos /p/nome/ daquele perfil desaparecem e served_profiles é atualizado na mesma hora. Não sobra adaptador meio morto ocupando memória nem segurando o token do bot.
O rescan de 30 segundos como rede de segurança
O ping no socket de controle é o caminho rápido, e caminhos rápidos falham: o gateway pode estar subindo, o socket de controle pode ainda não estar escutando, ou simplesmente não vem resposta. Por isso a mudança também traz um watcher supervisionado que relê profiles/ a cada 30 segundos (a constante no código é _PROFILE_RESCAN_INTERVAL_SECS = 30.0). O serviço imediato é o melhor esforço; a garantia de correção vem da passagem periódica por baixo.
O cliente do socket de controle é rescan_gateway_profiles(home, timeout=8.0), que envia rescan-profiles e normalmente devolve um resultado com served_profiles, added, removed e outros campos. O detalhe interessante é a degradação deliberada: se nenhum gateway responder, ou se o que responder for uma versão antiga, a chamada devolve None. Quem chamou não falha: volta para o rescan periódico, o que na linha de comando significa manter o velho aviso de reiniciar. Na direção contrária a tolerância é a mesma: uma instalação antiga do Hermes não cai porque um cliente novo fez uma pergunta que ela não entende.
Os rescans são baratos porque a detecção de assinatura não percorre o conteúdo do diretório: ela olha exatamente dois arquivos, config.yaml e .env, e compara o (mtime_ns, size) deles. São as constantes _PROFILE_SIGNATURE_FILES = ("config.yaml", ".env"). É também por isso que colar credenciais provoca uma reconstrução: você salva o arquivo, o mtime muda, a assinatura muda. Qualquer outra alteração por perto, como um log novo ou um cache esquecido, não gera alarme falso.
A implementação fica num módulo novo, gateway/run_profile_reconcile.py, acoplado ao ambiente de execução do gateway como GatewayProfileReconcileMixin — mais um reconciliador que fica de olho no diretório profiles/ do que mais uma camada de gerenciamento de processos.
cron, descoberta MCP e roteamento de logs vêm junto
Um perfil novo não é só mais um bot. Os temporizadores do cron passaram aqui a usar um enumerador vivo, então as tarefas agendadas de um perfil recém-criado realmente disparam, em vez de serem ignoradas por não constarem no instantâneo da inicialização. Perfis novos também ganham descoberta MCP e roteamento de logs. São esses detalhes que tornam honesta a frase “funciona assim que é criado” — sem eles, o seu bot novo responderia mensagens enquanto as próprias tarefas agendadas ficariam paradas.
Se você quer cada perfil rodando cron com o próprio bot, o guia de cron por perfil traz o exemplo completo.
Nada mais é interrompido
A pergunta que vale fazer sobre o serviço a quente é se ele reinicia todo mundo de fininho no meio do caminho. Não. Durante toda a passagem de reconciliação, os outros perfis servidos ficam totalmente intactos: o mesmo pid, as mesmas contagens de sondagem, e as conversas em andamento não são interrompidas. A reconciliação toca apenas a diferença — acrescenta o que é novo, desmonta o que sumiu e deixa exatamente como está tudo o que já está correto.
Aí está a diferença real em relação a reiniciar o gateway. Um restart derruba o processo e todos os adaptadores junto, e reconstrói tudo. A reconciliação muda só a parte que precisa mudar. Para um gateway multiplex, é isso que a palavra “a quente” deveria significar.
O que você vai ver na interface
O sinal mais visível é um aviso que deixa de aparecer. O endpoint de configuração de plataformas (um PUT para /api/messaging/platforms/ com o id da plataforma) agora devolve um campo hot_served. Quando ele vale true, tanto o desktop (nos seis idiomas) quanto o painel pulam o aviso de que é preciso reiniciar.
O hermes profile create também confirma o serviço a quente diretamente. O lembrete de reiniciar só permanece quando o multiplexador de fato não pegou o perfil — por exemplo, quando não há gateway rodando ou quando o socket de controle não respondeu.
Como usar
- Confirme que a multiplexação está ligada:
gateway.multiplex_profiles: true. - Crie o perfil:
hermes profile create nightshift. - Coloque o token do bot no
.envou noconfig.yamldele. Qualquer ordem serve; se você colar depois, a mudança de assinatura monta o adaptador para você. - Verifique com
hermes gateway statusse o perfil aparece entre os que estão sendo servidos. - Se ele não aparecer: dê até 30 segundos para o rescan de segurança. Se ainda assim não aparecer,
hermes gateway restartcontinua sendo a saída de emergência. Um gateway antigo não conhece o verborescan-profiles, e nesse caso reiniciar é o único caminho — então confirme primeiro se o seu Hermes é novo o bastante para incluir esta mudança.
Resumindo
Esta mudança não adiciona nenhum comando novo. Ela muda como o gateway multiplex reage a mudanças: enumerar uma vez na inicialização vira reconciliar em execução. Perfis novos são servidos na hora, credenciais tardias reconstroem o adaptador, perfis removidos são desmontados e saem do roteamento, um rescan a cada 30 segundos cobre a falha do caminho rápido, e perfis que já estavam sendo servidos nunca são tocados. Se quiser conferir por conta própria, tests/gateway/test_multiplex_hot_serve.py tem três casos que correspondem aos três caminhos: um perfil criado é servido, credenciais adicionadas montam um adaptador e um perfil removido tem o roteamento cancelado.
Para o panorama maior de rodar vários perfis na mesma máquina, veja vários perfis em paralelo; para controlar quais perfis podem servir bots, a lista de permissões de perfis do gateway entra em mais detalhes.
Uma nota de versão, porque isso importa: isto chegou à main em 2026-09-12 e faz parte do trabalho posterior à v0.21.2, lançada em 2026-09-11. Ainda não saiu em nenhuma versão marcada, então se você quiser hoje, você quer a main.