Language Packs: o Hermes fala 17 línguas — e o português que traz é do Brasil

Por SkyNet · 6 de outubro de 2026

O Hermes fala 17 línguas, mas vale a pena perceber o que isso significa ao certo. O que está traduzido é o texto estático da interface: os prompts de aprovação no terminal, as respostas que o gateway devolve nos chats, os tips, o CLI, o hermes --tui e o Hermes Desktop. O que fica de fora é deliberado — respostas do agente, output das ferramentas, logs e até os nomes dos slash commands. Para o agente te responder noutra língua, pedes-lho no prompt; o catálogo não mexe nisso.

A parte boa é que essa lista é plugável. Um language pack é um plugin sem uma linha de Python: um plugin.yaml e uma pasta locales/. E há uma via ainda mais barata — um único ficheiro YAML em ~/.hermes/locales/ sobrepõe a redação que vier de fábrica.

17 línguas, uma cascata de camadas

A lista incluída é en, af, ar, de, es, fr, ga, hu, it, ja, ko, pt, ru, tr, uk, zh, zh-hant. Ver e trocar é direto:

hermes config get display.language
hermes config set display.language pt
hermes plugins list

A resolução é em cascata: um lang= explícito ganha a HERMES_LANGUAGE no .env (que é por perfil), que ganha a display.language, que por fim cai em en. O texto sai da primeira camada que tenha a chave: packs instalados, depois o teu overlay locales/<lang>.yaml, depois o catálogo bundled, e a mesma cadeia outra vez para o inglês. Todas as camadas podem ser parciais — só precisas das chaves que queres mudar.

Um id que não exista é recusado com a lista toda, e a mensagem já diz o que fazer:

✗ Unknown language 'zz' for display.language. Available: en, af, ar, de, es, fr, ga, hu, it, ja, ko, pt, ru, tr, uk, zh, zh-hant.
  Install a language pack plugin (hermes plugins install <pack>) or drop <HERMES_HOME>/locales/<id>.yaml to add one.

O português que traz é do Brasil

Agora o que interessa a quem escreve português de Portugal. O catálogo pt bundled é PT-BR, e não é subtil. Abre o locales/pt.yaml e encontras denied: "Você negou {noun} — nada foi executado.", cancelled: "O pedido de aprovação foi retirado ou nunca chegou até você — {noun} não rodou.", file: "arquivo" e hint_rate_limited: " Você está sendo limitado por taxa…". O catálogo do TUI vai na mesma linha: billing.autoReload.authorization: "… você autoriza a Nous Research a cobrar {0} …".

A tentação é pôr display.language: pt-pt e seguir caminho. Não resolve: pt-pt, pt-br, brasileiro e português são todos aliases do mesmo catálogo pt (_LANGUAGE_ALIASES, em agent/i18n.py). O hermes config set guarda o valor como o escreveste — fica pt-pt no config.yaml — mas em runtime o _normalize_lang resolve-o para pt, ou seja, para o português do Brasil. Só um pack ou overlay com um id real pt-pt ganha ao alias, porque um id fornecido vence sempre um alias.

A solução mais barata: um ficheiro

Não precisas de plugin nenhum. Basta um overlay parcial com as chaves que te incomodam:

# ~/.hermes/locales/pt-pt.yaml — só as chaves que queres mudar
approval:
  summary:
    denied: "Negaste {noun} — nada foi executado."
  inputs:
    approve: "approve,yes,ok,confirm,aprovar,sim"

E é aqui que a coisa muda de figura: um overlay que declara uma língua que o Hermes não inclui torna essa língua selecionável. Com esse locales/pt-pt.yaml no sítio certo, hermes config set display.language pt-pt responde ✓ Set display.language = pt-pt, e o pt-pt passa a aparecer na lista de disponíveis. As edições são lidas no arranque seguinte ou na mudança seguinte de display.language. Num perfil nomeado, o sítio é ~/.hermes/profiles/<nome>/locales/.

Traduzir tudo à mão é trabalho, mas o locales/pt.yaml bundled serve de base: copia-o, corrige o registo e usa-o como overlay. É a diferença entre “o Hermes fala português” e “o Hermes fala o meu português”.

A solução completa: um pack a sério

Se queres distribuir isto — ou fazer o mesmo para o TUI e o Desktop — o pack é a resposta. O layout mínimo:

hermes-lang-pt-pt/
  plugin.yaml
  locales/
    pt-pt.yaml            # core: approval.*, gateway.*, cli.*, display.*, slash.*, tips.*
    pt-pt.tui.yaml        # opcional: hermes --tui
    pt-pt.desktop.yaml    # opcional: Hermes Desktop

E o manifesto:

# plugin.yaml
name: hermes-lang-pt-pt
version: 1.0.0
description: Portuguese (Portugal) wording for Hermes
provides_locales:
  - id: pt-pt            # tag minúsculo tipo BCP-47: pt-pt, pt-br, zh-hant
    endonym: Português (Portugal)   # mostrado no seletor de línguas
    rtl: false           # true inverte o layout do Desktop (script RTL)

Com provides_locales declarado, o loader regista sozinho todos os locales/<lang>[.tui|.desktop].yaml. E o validador confirma o que fizeste:

$ hermes plugins validate ./hermes-lang-pt-pt
✓ manifest — plugin.yaml parses
✓ manifest fields — name, version, description present
✓ requires_hermes — not declared
✓ config schema — not declared
✓ requires_env — all entries UPPER_SNAKE
✓ loadable — entry: locales/ (language pack)
✓ python dependencies — none declared
✓ capability probe — skipped (no __init__.py)
✓ built-in tool collisions — no tools to check
✓ security scan — safe
✓ no core override — no runtime rebinds of Hermes core
✓ locale pt-pt — pt-pt.yaml: 2 key(s), 2 match the English core catalog
⚠ no __init__.py — capability probe skipped (manifest-only plugin)
◆ Isolation — portable plugin (no Python): runs anywhere

Validation passed.

Depois de instalar (hermes plugins install <nome|git-url|owner/repo>), reinicia os gateways e os TUIs para apanhar o pack. Os seletores de língua listam as línguas bundled, os overlays e os packs instalados pelo endonym — o nome nativo, sem bandeiras.

O que costuma correr mal

  • Um valor que não é texto mata a validação. Um número, uma lista, um true/false ou um valor vazio é erro: ✗ locale pt-pt — pt-pt.yaml has non-text value(s) at: approval.allowed_once. E nunca uses palavras reservadas do YAML (on, off, yes, no) como chaves.
  • Chaves que não existem em inglês são aviso, não erro. O validador lista-as (⚠): ficam no ficheiro, mas não fazem nada.
  • Placeholders. No core usas o nome exato do inglês ({count}); nas entradas de TUI e Desktop que em inglês são funções, escreves posicionais ({0}, {1}). Um placeholder em falta ou mal escrito faz a chave cair para o inglês — e não te avisam.
  • Já há packs no catálogo. hermes plugins search "language pack" mostra o hermes-zh (chinês simplificado, sobreposição parcial de approval.*/gateway.*) e o hermes-lang-vi (vietnamita, core + TUI + Desktop), este último com requires_hermes: >=0.22. Se estás na v0.21.5, que é a versão estável atual, o pack vietnamita avisa ou recusa até saíres da versão.

Fecho

O arranjo é engenhoso: as línguas são mais uma camada sobreponível — bundled, overlay, pack, por perfil — em vez de uma lista fechada. E este tema é mesmo para um blog português, porque é aquele caso em que “suporta português” e “suporta o nosso português” são coisas diferentes. O pt-pt já está lá, só que aponta para São Paulo. Um ficheiro de vinte linhas resolve-o.

Docs: Language Packs · Release v2026.9.24

Tags: #hermes #i18n #linguas #personalizacao