Plugins de terceiros saem do processo principal: por dentro de plugins.isolation: host


Imagine uma máquina que carrega vários profiles: o seu, um compartilhado com o time e um profile de demonstração para clientes. Alguém instala um plugin da comunidade — uma coisinha que conecta um sistema de tickets ao chat. No momento em que ele é importado, esse plugin passa a viver no mesmo processo Python que cada sessão, cada credencial de provider e cada chave de API na memória. Um autor de plugin com boas intenções ainda pode entregar uma variável global, um monkeypatch ou uma thread que nunca encerra, e tudo isso pode alcançar coisas que nunca deveria tocar.

O Hermes agora oferece um interruptor para isso: tirar os plugins de terceiros do processo principal. A configuração é uma linha, plugins.isolation: host, e o plugin em si não muda nada.

O padrão não mudou; o novo modo é um host por profile

Sejamos precisos, porque nada muda até você pedir. O padrão continua sendo in_process: os plugins são importados para dentro do processo do Hermes, exatamente como antes. Só um host explícito altera o comportamento.

plugins:
  isolation: host        # padrão: in_process
  host:
    launcher: []         # prefixo argv opcional para o host, p. ex. um sandbox runner

Com host, cada profile ganha um processo Python separado, iniciado sob demanda — o plugin host —, que importa apenas os plugins instalados pelo usuário daquele profile e conversa com o Hermes por um pipe privado. Plugins empacotados (bundled) não são afetados e continuam rodando in-process.

Um detalhe de projeto é fácil de passar batido e importa muito: o processo host inicia com apenas o ambiente e os secrets daquele profile. Antes, um plugin via quais credenciais o processo carregava; agora vê as do próprio profile. Em um deployment multi-tenant, esse é o sentido prático de “o código de plugin de um inquilino nunca compartilha memória com os dados de outro”.

Os plugins não mudam: o mesmo ctx, serializado pelo pipe

A parte chata da maioria das histórias de isolamento é que você precisa reescrever código. Aqui não.

Dentro do host, um plugin recebe o mesmo ctx de sempre. Ferramentas, hooks, comandos de barra, comandos de CLI, skills e objetos de provider (geração de imagem e vídeo, busca na web, navegador, TTS/STT, memória, context engines, cron) se registram exatamente como antes. O Hermes registra do seu lado proxies equivalentes que chamam o host quando necessário — a documentação chama de RemotePluginContext o objeto entregue aos plugins.

Ele também é reentrante: enquanto trata uma chamada de ferramenta, um plugin pode chamar de volta o Hermes por meio de ctx.dispatch_tool, ctx.get_config ou ctx.llm — e o Hermes o aguarda, como se o plugin ainda fosse local. Para os autores de plugins, isso é praticamente isolamento de graça.

Existe um preço, e ele é publicado em vez de descoberto. Algumas superfícies realmente precisam de código in-process, e sob host esses plugins são recusados com um motivo claro, em vez de perder recursos silenciosamente. A lista documentada: adaptadores de plataforma do gateway (register_platform), transportes de aprovação, handlers de Telegram e de outras plataformas, profiles de model provider que criam o próprio cliente SDK (create_client), endpoints de dashboard em streaming e plugins que dão monkeypatch em módulos do Hermes. Rode esses com isolation: in_process.

As falhas ficam dentro do host

O primeiro ganho do isolamento não é segurança, é estabilidade. Sob host:

  • o módulo de um plugin nunca entra no processo do Hermes, então não pode ler da memória os dados de outro profile nem aplicar patch nas entranhas do Hermes;
  • um plugin que quebra ou encerra mata o seu host, não o Hermes. A chamada em andamento retorna um erro de ferramenta, depois o Hermes reinicia o host e recarrega seus plugins (com retries limitados) enquanto todas as outras sessões seguem rodando.

Se você já instalou um plugin e viu o gateway inteiro cair junto com ele, esta seção é para você.

Ligar, conferir, fixar

Ative com o bloco de config acima. Dois comandos dizem a verdade na hora:

# Verifica se um plugin pode rodar em modo host; explica qualquer recusa
hermes plugins validate <dir>

# Veja onde um plugin específico roda
hermes plugins show <name>

host.launcher existe para setups mais rígidos: ele recebe um prefixo argv que envolve o processo host no seu próprio sandbox runner. A documentação também recomenda rodar o terminal do agente em um backend isolado (Docker, SSH e assim por diante) — isolar o plugin enquanto o próprio terminal do agente ainda consegue ler os arquivos do operador te dá só metade do isolamento.

Depois vem o problema mais prático em deployments compartilhados: plugins.isolation é config comum de profile, então qualquer um que consiga editar o config.yaml de um profile consegue desligá-la. Quando os profiles pertencem justamente às pessoas que você está isolando umas das outras, fixe o valor no managed scope — um /etc/hermes/config.yaml de propriedade do root que todos os profiles leem. O valor gerenciado vence a config de cada profile, e o hermes config set se recusa a alterá-lo:

# /etc/hermes/config.yaml (propriedade do root; lido por todos os profiles da máquina)
plugins:
  isolation: host
  host:
    launcher: [...]

Quanto do catálogo está pronto

A preocupação óbvia: se eu ligar isso, meus plugins instalados ainda vão funcionar?

A documentação dá o número da época em que foi escrita: 299 das 348 entradas do catálogo de plugins rodam no host sem alterações. É esse o valor real da lista de não suportados acima — ela transforma “isso vai quebrar?” em uma lista curta e verificável, em vez de um experimento na sua própria máquina.

Quando você pode ter isso

O recurso foi mergeado na branch main em 3 de outubro de 2026. A release mais recente é a v0.21.5 (tag v2026.9.24), então no momento ele vive só na main e ainda não está em nenhuma release com tag. Instalações que acompanham a main o recebem no próximo hermes update; quem usa releases terá no próximo tag.

Para o sistema de plugins como um todo — fontes de instalação, a allow-list de habilitação, diretórios de subcategoria — veja o guia do catálogo de plugins. Remoções do catálogo e regras de cadeia de suprimentos são tratadas no artigo sobre o gate de CI do catálogo, e se a sua dor é “tenho que reiniciar para uma mudança de plugin fazer efeito”, o guia de rewire de plugins ao vivo combina mais.

A versão curta

Instalar um plugin costumava significar convidar o código de outra pessoa para dentro do seu processo. Agora você pode mantê-lo do lado de fora, e o plugin nem percebe a diferença. Em um notebook de usuário único, você provavelmente nunca vai tocar nessa linha. Em uma máquina que carrega várias pessoas ou inquilinos, ela pertence à categoria dos interruptores que você gostaria de ter ligado antes do incidente, não depois.

Se você opera um deployment compartilhado, faça duas coisas: rode hermes plugins validate sobre tudo o que você instalou e depois escreva plugins.isolation: host no managed scope, em vez de deixar cada profile decidir.