Языковые пакеты

В Hermes встроено 17 языков интерфейса (display.language), и список можно расширять. Языковой пакет — это плагин (или папка в домашнем каталоге Hermes), который добавляет новый язык или переопределяет формулировки уже существующего. Один пакет покрывает Python-часть (запросы подтверждения в CLI, ответы шлюза, глаголы инструментов, подсказки), интерфейс hermes --tui и десктопное приложение.

Пакет переводит статический текст интерфейса. Ответы агента, вывод инструментов, логи и имена slash-команд остаются как есть. Чтобы сам агент отвечал на другом языке, скажите ему об этом в промпте.

Откуда берутся языки

Когда Hermes ищет строку, он идёт по слоям сверху вниз и берёт первое совпадение:

  1. Языковые пакеты плагинов — каждый установленный плагин, который объявляет provides_locales (если два пакета покрывают один ключ, побеждает загруженный последним).
  2. Ваш оверлей — <HERMES_HOME>/locales/<lang>.yaml (у каждого профиля своя папка locales/ в его домашнем каталоге).
  3. Встроенные — файлы locales/<lang>.yaml, которые поставляются с Hermes.
  4. Те же три слоя для английского, а затем сам ключ как есть.

Любой слой может быть неполным: пакету или оверлею нужны только те ключи, которые они меняют.

hermes config set display.language <id> принимает любой id, который даёт один из этих слоёв. Неизвестные id отклоняются со списком доступных языков:

$ hermes config set display.language pl
✗ Unknown language 'pl' for display.language. Available: en, af, ar, de, es, ...
  Install a language pack plugin (hermes plugins install <pack>) or drop <HERMES_HOME>/locales/<id>.yaml to add one.

Как подключить пакет

hermes plugins install https://github.com/teknium1/hermes-lang-pl   # or a catalog name
hermes config set display.language pl

Перезапустите работающие шлюзы и TUI, чтобы они подхватили пакет. Переключатели языка в TUI и десктопе показывают встроенные языки, языки вашего оверлея и все установленные пакеты под их родными названиями (эндонимами). Запись HERMES_LANGUAGE в .env по-прежнему перекрывает display.language.

Как написать пакет

Python-код пакету не нужен. Минимальная структура:

hermes-lang-pl/
  plugin.yaml
  locales/
    pl.yaml            # core: Python-side strings (approval.*, gateway.*, cli.*, display.*, slash.*, tips.*, ...)
    pl.tui.yaml        # optional: hermes --tui strings
    pl.desktop.yaml    # optional: Hermes Desktop strings

plugin.yaml:

name: hermes-lang-pl
version: 1.0.0
description: Polish language pack for Hermes
provides_locales:
  - id: pl            # lowercase BCP-47-style tag: pl, pt-br, zh-hant
    endonym: Polski   # shown in language switchers
    rtl: false        # true for right-to-left scripts (flips the Desktop layout)

Записи в provides_locales могут быть и просто id (- pl); тогда эндоним по умолчанию равен id. Если манифест объявляет provides_locales, загрузчик плагинов сам регистрирует каждый файл locales/<lang>[.tui|.desktop].yaml.

Файлы и ключи

  • pl.yaml (core) повторяет структуру встроенного locales/en.yaml. Вложенный YAML разворачивается в ключи через точку (approval.denied, gateway.goal_cleared). Скопируйте en.yaml, переведите значения, а всё, что переопределять не нужно, удалите.
  • pl.tui.yaml / pl.desktop.yaml повторяют английские каталоги TUI и десктопного приложения. Наборы ключей экспортируются в locales/_keys.tui.json и locales/_keys.desktop.json в репозитории Hermes, и именно по ним сверяется валидатор.
  • Значения в YAML должны быть текстом. Число, список, true/false и пустое значение отклоняются.
  • Не используйте зарезервированные слова YAML (on, off, yes, no) в качестве ключей.

Плейсхолдеры

  • Строки ядра (Python) используют именованные плейсхолдеры точно так же, как английские: "⏳ Draining {count} active agent(s)...". Сохраняйте каждый {name} из английского значения: если плейсхолдер пропущен или написан с ошибкой, Hermes для этого ключа вернётся к непереведённой строке.
  • Записи TUI и десктопа, у которых английское значение — функция (принимает аргументы), в YAML пишутся строками с позиционными плейсхолдерами: "{0} of {1} sessions".

Валидация

hermes plugins validate ./hermes-lang-pl

Валидатор проверяет, что для каждого объявленного id есть locales/<id>.yaml, что каждый файл разбирается и содержит только текст (нетекстовое значение — ошибка). Ключи, которых нет в английском каталоге этой поверхности, валидатор перечисляет в предупреждении: они безвредны, но ничего не делают. Проверки .tui.yaml / .desktop.yaml выполняются, когда есть соответствующий экспорт _keys.*.json.

Регистрация из Python (необязательно)

Плагин, в котором уже есть Python-код, может сам регистрировать каталоги:

from pathlib import Path

def register(ctx):
    here = Path(__file__).parent
    ctx.register_locale("pl", here / "locales" / "pl.yaml", endonym="Polski")
    ctx.register_locale("pl", {"approval": {"denied": "      ✗ Odrzucono"}})          # dict, nested or flat
    ctx.register_locale("pl", here / "locales" / "pl.tui.yaml", surface="tui")
    ctx.register_locale_dir(here / "locales")                                         # everything at once

register_locale(lang, source, *, endonym=None, rtl=False, surface="core") принимает путь к YAML или словарь; surface — это core, tui или desktop. Регистрация отменяется при выгрузке плагина и никогда не меняет display.language.

Личные правки без плагина

Положите неполный файл в домашний каталог Hermes:

# ~/.hermes/locales/en.yaml — only the keys you want to change
approval:
  denied: "      ✗ Nope."

Оверлей действует только на этот профиль (для именованного профиля — в ~/.hermes/profiles/<name>/locales/). Файлы оверлея для языка, которого в Hermes нет, тоже делают этот язык доступным для выбора. Правки читаются при следующем запуске или при следующей смене display.language.

Устранение неполадок

  • Unknown language ... for display.language — пакет не установлен или не включён (hermes plugins list), либо id в provides_locales не совпадает с именем файла (для pl нужен locales/pl.yaml).
  • Переведённая строка всё равно показывается по-английски — ключа нет в английском каталоге (запустите hermes plugins validate: неизвестные ключи будут перечислены) или набор плейсхолдеров отличается от английского.
  • Язык в списке есть, а TUI/десктоп всё ещё на английском — в пакете нет .tui.yaml / .desktop.yaml; эти поверхности показывают английский плюс то, что даёт пакет. Для 16 встроенных языков TUI поставляет собственный locales/<lang>.tui.yaml в дереве Hermes (десктоп вшивает переводы в приложение), так что пакету для любого из них нужны только ключи, которые он хочет переопределить.
перевод и редактура:

обновлено

⌕ ESC