Hermes Agent v0.21.5
Visão Geral
v0.21.5 — mais uma tag que existe para consumidores downstream. Publicada em 24 de setembro de 2026. Desde a v0.21.4: 1.610 commits não-merge · 4.828 arquivos alterados (+164.132 / −149.440) · 460 PRs mesclados · 475 issues fechadas, medidos no commit f97608f178d1ffeca59860195ab7da295f7c8e5f.
A tag existe pelo mesmo motivo que a v0.21.4: as imagens Docker, o Hermes Cloud e as implantações hospedadas são todos construídos a partir da tag de release mais recente, então as correções desta janela precisam chegar a uma versão estável antes que os usuários de nuvem possam recebê-las. O corpo da release diz isso sem rodeios — o texto curado completo fica adiado para a v0.22.0, que vai documentar tudo a partir da v0.21.0: destaques, áreas de funcionalidade e créditos completos de contribuidores. Nada desta janela é deixado de fora.
Até lá, esta página registra para quem a tag existe e as mudanças da janela que já estão rodando na sua máquina.
Destaques
1. O Desktop ganha catálogos completos de francês, alemão e espanhol, além de uma configuração de direção do texto
O Desktop agora traz catálogos de interface completos para francês, alemão e espanhol, listados em Settings → Appearance → Language. Os três catálogos traduzem todas as chaves de en.ts, incluindo todos os rótulos e descrições de configurações de defineFieldCopy e a rotação de intro apenas de exibição (intro-{fr,de,es}.ts). Eles se registram como overlays defineLocale(), assim como ja, ar e ru, então uma chave adicionada depois ao inglês cai de volta no inglês em vez de quebrar o typecheck de todos os contribuidores. O backend já traz locales/{fr,de,es}.yaml; display.language: fr|de|es e aliases regionais como fr-CA, de-AT e es-419 agora resolvem para o catálogo correspondente em vez de cair de volta no inglês. O francês usa vous, o alemão usa Sie e o espanhol usa o imperativo neutro tú. Nomes próprios e identificadores técnicos (Hermes, MCP, API, OAuth, IDs de modelo, variáveis de ambiente, nomes de arquivo) permanecem sem tradução. PRs #120829.
Ao lado disso vem Appearance → Chat display → Text direction, com três opções: Auto / Right-to-left / Left-to-right. Até agora cada bloco de prosa do chat e cada linha do composer escolhia a sua direção base pelo primeiro caractere forte (UAX#9 plaintext), o que não consegue distinguir um parágrafo em árabe que começa com um nome latino de um parágrafo em inglês citando árabe. Auto é exatamente o comportamento antigo — nenhum atributo novo, nenhuma chave de armazenamento; escolher RTL ou LTR aplica um único dir à prosa do chat e aos dois composers, incluindo todas as linhas de um rascunho com várias linhas. O código permanece LTR (blocos de código, código inline e KaTeX continuam isolados) e a moldura do app (barra lateral, barra de ferramentas, botões do composer) não vira. É só apresentação: nenhum caractere de controle bidi entra em rascunhos, mensagens enviadas ou texto copiado. A preferência pertence ao renderer, não é uma chave do config.yaml. PRs #120822.
2. Entregas de webhook podem ser espelhadas na sessão do chat de destino
Por padrão uma entrega é fire-and-forget: cada evento roda na própria sessão, então responder “então ele saiu?” naquele chat recebe de volta “a quem você está se referindo?”. Uma rota agora pode aderir com mirror_to_session: true (ou hermes webhook subscribe … --mirror-to-session), e depois de um envio bem-sucedido o texto entregue é anexado à sessão do chat de destino como [Webhook delivery: <route>] mais a mensagem, na forma de um turno user rotulado com autoridade de usuário — o mesmo caminho e a mesma convenção de papel dos briefs de cron continuáveis (gateway.mirror.mirror_to_session). Desligado por padrão; só um booleano true de verdade adere. O espelhamento roda dentro de _profile_scope(profile), então uma rota /p/<profile>/ grava no state.db daquele profile e nunca no de outro. É best-effort: nunca faz a entrega falhar e é pulado quando o chat ainda não tem uma sessão de gateway. Numa rota deliver_only o texto espelhado é o payload renderizado bruto, então ative isso apenas para fontes em que você confia que fiquem na sua conversa. PRs #120825.
3. O Bot Screen chega a imagens hospedadas por meio das tags -desktop
Implantações hospedadas e imutáveis agora ganham o Bot Screen baixando uma tag de imagem -desktop. A imagem publicada sai sem Xvnc/Xfce e não consegue instalar em tempo de execução (hermes sem privilégios, sem sudo, /opt/hermes selado), então a camada da imagem é o único caminho de entrega. :latest / :main / :v* são a imagem que já são hoje; :latest-desktop / :main-desktop / :v*-desktop adicionam os pacotes e o Chromium com interface do Playwright. Um manifesto por variante, então uma falha na publicação do desktop não pode pular o :latest do slim. Contêineres não têm logind, então XDG_RUNTIME_DIR=/tmp/hermes-runtime é criado com 0700 como hermes na inicialização — o antigo fallback $HOME/.cache caía no volume compartilhado /opt/data, onde duas instâncias disputavam um único lock de display — e um diretório pertencente a outro usuário ou com symlink é recusado em vez de receber chown. PRs #120914; o doc do recurso é website/docs/user-guide/features/bot-screen.md.
4. Adicione um modelo por slug em todos os seletores de modelo
O menu de modelos do composer, o diálogo de troca de modelo, Settings → Model e a lista de edição de modelos agora todos podem adicionar um modelo por slug: uma nova linha de rodapé Add custom model… transforma a caixa de busca em entrada de slug, oferecendo uma linha por provider configurado conforme você digita, e o slug memorizado permanece na lista como uma linha normal com um × de remoção. PRs #120693.
5. Vozes locais param de recarregar a cada ativação
tts.keep_warm_seconds (padrão 60) é novo: depois que o último lease é liberado, o descarregamento espera esse tempo, e qualquer toggle que reative a fala dentro da janela o cancela e reutiliza o modelo carregado. 0 descarrega imediatamente. Isso importa principalmente para conversas de voz apenas por ativação, que terminam logo depois do aquecimento de ~2s do Piper — a voz costumava ser descartada milissegundos depois de carregar, então cada ativação pagava o recarregamento completo. PRs #121080.
6. O loop de voz do desktop passa a ler a sua configuração
O Read Aloud não fala mais placeholders em inglês como “code block omitted” e “link”, e não descarta mais tabelas Markdown: blocos de código e URLs ficam mudos, tokens de link de arquivo MEDIA: nunca chegam à voz (a pontuação logo depois de um token inline é mantida), dois-pontos no fim da linha, deixados pendurados por um bloco removido, viram um ponto final, e as tabelas falam a sua linha de cabeçalho (“Item, Value, Notes.”) pulando as linhas de corpo. PRs #120752. O spoken stop agora lê voice.stop_phrases (padrão ["stop"]) — antes ele casava com uma lista fixa em inglês, então um usuário russo dizendo “отбой” conforme o aviso instruía tinha isso enviado ao agent como prompt — e a fala inteira precisa ser igual a uma frase, com [] desativando o spoken stop. A reprodução com barge-in não usa mais um gatilho fixo de 0.14, que ficava acima do nível de fala de um headset Bluetooth HFP enquanto uma resposta toca, e é por isso que falar por cima da resposta nunca a interrompia; agora ela usa o já existente voice.barge_in_threshold_multiplier (padrão 3.0). PRs #120751.
7. Atalhos de voz por tecla de função são remapeáveis
O ditado pontual do composer agora é uma ação de teclado composer.dictate sem binding, separada da conversa por voz, reutilizando o caminho de captura canônico do Desktop para teclas F, Caps Lock, Delete, Space e combinações de modificadores. O campo obsoleto voice.record_key do Desktop foi removido, com uma nota de que a configuração continua apenas para CLI/TUI. A arbitragem do Electron faz com que um F12 atribuído chegue ao renderer enquanto um F12 não atribuído mantém o comportamento do DevTools. PRs #120928. Na mesma janela, os fluxos de trabalho por tecla de função no macOS foram corrigidos: o parser da TUI mantém as sequências de terminal F1–F12 intactas (incluindo os caminhos de protocolo com tecla modificada), e Ctrl+R foi adicionado como fallback portátil do F7 para o dock de trabalho ao vivo na TUI e no CLI clássico. PRs #120666.
8. Uma leva de falhas que só atingiam Windows localizados
Quatro problemas independentes, exclusivos do Windows:
- O crash do nome de fuso. O Windows devolve nomes de fuso na code page ANSI (
Paris, Madrid (heure d'été)como bytes cp1252). QuandoLC_CTYPEé UTF-8, esses bytes são decodificados comsurrogateescape, entãotzname()acaba guardando surrogates soltos;datetime.strftimeinseretzname()no formato como UTF-8, então%ZlevantaUnicodeEncodeErrordentro dostrftime— antes de existir qualquer string que a passada existente_sanitize_surrogatespudesse limpar. O system prompt é reconstruído no início de cada conversa e a cada compactação, então a falha voltava sempre. O novohermes_time.safe_strftime()é byte a byte idêntico aostrftimeem locales saudáveis (o invariante do cache de prefixo se mantém) e, caso contrário, decodifica os bytes escapados como surrogate pela code page ANSI. PRs #120748. - Decodificação de processos filhos no Windows chinês. O
_readerthreaddesubprocess.communicate()no Windows decodifica a saída do filho comsubprocess._text_encoding()—locale.getencoding(), cp936/GBK no Windows chinês — sempre que uma captura passatext=Truesemencoding=. Os filhos em questão escrevem UTF-8, então qualquer byte ilegal em GBK levantaUnicodeDecodeErrornaquela thread, que othreading.excepthookdo processo serve imprime como uma linha[gateway-crash]. Ohermes_cli/web_routers/files.py::_fs_git_branchera um desses (os seus kwargs ficam num literal de dict, então a regra baseada em linha detext=Truenunca o pegava) e o Desktop faz polling dele continuamente. PRs #120749. - Caminhos absolutos do Windows.
C:\...\report.htmle caminhos UNC\\server\share\...não eram reconhecidos como caminhos (então nenhuma tag de artefato aparecia) nem eram deixados em paz pelo fallback do renderer, que tratava tudo que não começasse com/como relativo e juntava ao cwd, produzindo caminhos como/repo/C:\...; o rótulo da pré-visualização então interpretavaC:como esquema de URL. O novoisWindowsAbsolutePathaceita uma letra de unidade com qualquer uma das barras e um prefixo UNC. PRs #121074. - A sonda de boot em cold start. Num cold start do Windows o backend local responde HTTP e depois o seu event loop trava por 12–28s enquanto o GIL fica retido importando os módulos de plataforma do gateway. A sonda WebSocket de boot desistia depois de 10s fixos, travando um status de falha de boot, derrubando o processo filho e entrando na cascata “Ignoring stale Hermes backend exit (1)”. Um backend que este app gerou agora continua esperando além do orçamento-base de 10s enquanto o filho estiver vivo, até um teto de 90s — o mesmo orçamento que a etapa de anúncio de porta já concede a um cold start. O sinal de progresso é a vivacidade, não a recência da saída, porque a trava é silenciosa. Gateways remotos, o botão “Test remote” e a conexão ao backend host mantêm o orçamento fixo de 10s. PRs #120750.
Melhorias
- A leva do SDK de plugins do Desktop (API de rascunho do composer, slots de lista de sessões e de decoração de linhas, preferências de navegação da barra lateral, rótulos de pílulas de modelo, pontes tipadas de settings/skills/toolsets/profiles, uma primitiva de embed em sandbox, um slot de configurações de aparência, uma ponte pública de eventos para backends de plugins) chegou inteira nesta janela; o texto planejado para ela também fica adiado.
- A página Connectors substituiu a aba MCP, com “Connect now” para os servidores MCP de um plugin recém-instalado, e as tools e skills dos plugins instalados passam a funcionar em todos os chats abertos; o onboarding oferece plugins do catálogo ao lado dos conectores.
- O Kanban recebeu um passe de design: um modal de ticket em duas colunas e texto de tarefa em markdown.
- A janela também traz uma longa sequência de trabalho de performance nos caminhos críticos, cobrindo carregamento de configuração, o registro de tools, o tratamento de mensagens do gateway e o seletor de modelos.
Atualização
hermes update # instalações via git
# ou rode de novo o one-liner do instalador
Docker / Hermes Cloud: as imagens são construídas a partir desta tag, nousresearch/hermes-agent:v2026.9.24.
Changelog completo: v2026.9.21…v2026.9.24
← Hermes Agent ChangelogMapeamento de versão: a tag é baseada em data (
v2026.9.24) e a versão semântica é av0.21.5— a mesma release.