Queres que o Hermes use um sandbox de cloud específico como terminal? Agora escreves um plugin — sem esperar por alterações no core

Sempre quiseste que o Hermes corresse comandos de terminal num sandbox de cloud específico — código mais seguro, ambientes mais limpos, e sem mais conflitos de dependências locais. Depois abres a documentação e vês apenas os backends integrados listados. Aquele que queres implica esperar que os mantenedores fundam o código do fornecedor no repositório core, ou manter o teu próprio fork para sempre. O PR #94400, fundido a 25 de agosto, põe fim a essa espera: os backends de terminal são agora um subsistema pluggable. Um sandbox de cloud de terceiros pode registar-se como valor de terminal.backend através de um plugin autónomo — sem alterações no core, sem fork.
Porque é que esta era a “última grande peça”
Em todo o ecossistema de ferramentas do Hermes, a geração de imagem/vídeo, o web scraping, o browser, a memória, o TTS/STT e os fornecedores de modelos suportam integração no estilo plugin desde há muito — exceto os backends de terminal. Os terminais tocam em demasiados pontos sensíveis: aprovações, caminhos de contentores, caches, remoção de secrets — o maior raio de impacto de qualquer subsistema. O PR #94400 fecha essa lacuna: os fornecedores de sandbox podem agora escrever um plugin e deixar os utilizadores definir terminal.backend: <your-backend-name> diretamente.
Há um primeiro consumidor real por detrás disto: o backend de cloud-sandbox Sprites (originalmente #93523) foi o primeiro a migrar para esta interface — passou para um repositório de plugin privado e autónomo, em vez de viver no core.
Como é um plugin: uma ABC + uma função de registo
O mecanismo centra-se em dois ficheiros novos: agent/terminal_env_provider.py define a classe base abstrata TerminalEnvironmentProvider, e agent/terminal_env_registry.py é um registo thread-safe. O que um autor de plugin faz (o exemplo mínimo do guia oficial de developer, developer-guide/terminal-environment-plugin.md):
# ~/.hermes/plugins/acmebox/__init__.py
from agent.terminal_env_provider import TerminalEnvironmentProvider
class AcmeBoxEnvironment:
"""Tem de satisfazer o contrato duck-typed da BaseEnvironment."""
def __init__(self, cwd, timeout, task_id):
self.cwd, self.timeout, self.task_id = cwd, timeout, task_id
def execute(self, command, timeout=None, **kwargs):
... # executa o comando no sandbox
return {"output": "...", "exit_code": 0}
def cleanup(self):
... # encerra / desliga
class AcmeBoxProvider(TerminalEnvironmentProvider):
name = "acmebox"
display_name = "AcmeBox"
is_remote = True # os comandos não correm no host
is_container = True # semântica de path/cwd estilo contentor
@property
def cache_path_base(self):
return "~/.hermes" # onde os ficheiros de cache sincronizados vão parar, ou None
@property
def strip_env_keys(self):
return frozenset({"ACMEBOX_TOKEN"}) # secrets removidos dos subprocessos
def create_environment(self, *, cwd, timeout, task_id="default",
image=None, container_config=None, **kwargs):
return AcmeBoxEnvironment(cwd, timeout, task_id)
def register(ctx):
ctx.register_terminal_environment_provider(AcmeBoxProvider())
O diretório do plugin também traz um plugin.yaml (name, version, kind: backend). Depois ativa-o e seleciona-o:
hermes plugins enable acmebox
hermes config set terminal.backend acmebox
Os nomes de backends integrados (local, docker, singularity, modal, daytona, vercel_sandbox, ssh) estão reservados — os plugins alargam o conjunto, nunca fazem sombra a um integrado.
Seis flags de classificação que eliminam a classe de bugs “o novo backend esqueceu-se de um sítio”
No passado, adicionar um backend significava sincronizar a lógica de decisão por sete ou oito sítios no código — que backends são remotos, quais são contentores, quais saltam aprovações, como se traduzem os caminhos de cache — e falhar um era um bug difícil de encontrar (a issue #30112 exigiu uma varredura de sete sítios). O novo design declara tudo isto:
is_remote: os comandos correm noutro lugar que não o host. Suprime as dicas de OS/home/cwd do host, a sonda do ambiente Python do host e o tratamento de skills com noção de remoto;is_container: comporta-se como um contentor/sandbox com o seu próprio filesystem — a configuração de recursos do contentor passa, cwds com aparência de host são saneados, as ferramentas de ficheiros usam resolução de caminhos do contentor;skip_container_guards: o sandbox é suficientemente isolado para que os pedidos de aprovação de comandos perigosos sejam saltados (o padrão éis_container; backends que consigam montar caminhos do host devem substituir por False);cache_path_base: onde os ficheiros~/.hermes/cachesincronizados automaticamente vão parar dentro do backend (por exemplo,~/.hermesou/root/.hermes), ou None quando não há nada a traduzir;strip_env_keys: variáveis de ambiente com credenciais pertencentes a este backend (tokens de API do fornecedor), removidas de todos os subprocessos que o agente lança para que comandos escritos pelo modelo nunca as consigam ler;session_isolated_when_nonpersistent: o modo não persistente dá a cada sessão a sua própria identidade de sandbox, em vez de partilhar uma.
Onde o plugin aparece depois de registado
Um backend registado não é apenas um valor no ficheiro de configuração — todas as superfícies o reconhecem automaticamente:
- O seletor de backends do
hermes setupmostra a nova opção com configuração guiada pelo fornecedor; - O
hermes status/hermes doctorlistam o backend do plugin e o seu estado de saúde; - O seletor de backends de terminal do dashboard suporta backends de plugin e recalcula por pedido — um plugin instalado a meio de uma sessão aparece imediatamente.
O guia oficial de developer percorre a escrita de um backend plugin a partir do zero.
O que isto significa para os utilizadores comuns
Se só usas os backends integrados (terminal local, Docker, Modal, SSH), esta alteração é invisível em termos de comportamento — é uma porta arquitetural, não um interruptor de comportamento. O impacto no ecossistema é o que interessa: quando um fornecedor de sandbox diz “suporta Hermes”, passa a significar “instala o plugin”, não “espera por um merge no core”; a qualidade do plugin é responsabilidade do fornecedor, e o hermes doctor diz-te se está saudável. Para o básico sobre plugins, consulta a referência de comandos hermes plugins; para o mecanismo de entry-point por detrás dos fornecedores instalados via pip, o nosso guia de plugin de model provider via pip cobre a linhagem. A seleção de backends no dia a dia está documentada no guia de instalação.
Resumo
Backends de terminal pluggable transformam “fazer o Hermes usar o meu sandbox de cloud” de “implorar por um merge no core” em “escrever um plugin, declarar seis flags, registar, pronto”. É a última peça do ecossistema de ferramentas do Hermes a tornar-se plugin-native — os backends de terceiros estão agora desacoplados do core, com a política de segurança aplicada uniformemente através de flags declarativas.