Плагины

Hermes имеет систему плагинов для добавления пользовательских инструментов, хуков и интеграций без изменения основного кода.

Если вы хотите создать пользовательский инструмент для себя, своей команды или одного проекта, это обычно правильный путь. Страница Adding Tools руководства разработчика предназначена для встроенных основных инструментов Hermes, которые находятся в tools/ и toolsets.py.

Build a Hermes Plugin — пошаговое руководство с полным рабочим примером.

Краткий обзор

Поместите каталог с plugin.yaml и Python-кодом в ~/.hermes/plugins/:

~/.hermes/plugins/my-plugin/
├── plugin.yaml      # manifest
├── __init__.py      # register() — wires schemas to handlers
├── schemas.py       # tool schemas (what the LLM sees)
└── tools.py         # tool handlers (what runs when called)

Запустите Hermes — ваши инструменты появятся рядом со встроенными. Модель сможет вызывать их сразу.

Минимальный рабочий пример

Вот полный плагин, который добавляет инструмент hello_world и логирует каждый вызов инструмента через hook.

~/.hermes/plugins/hello-world/plugin.yaml

name: hello-world
version: "1.0"
description: A minimal example plugin

~/.hermes/plugins/hello-world/__init__.py

"""Minimal Hermes plugin — registers a tool and a hook."""

import json


def register(ctx):
    # --- Tool: hello_world ---
    schema = {
        "name": "hello_world",
        "description": "Returns a friendly greeting for the given name.",
        "parameters": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name to greet",
                }
            },
            "required": ["name"],
        },
    }

    def handle_hello(params, **kwargs):
        del kwargs
        name = params.get("name", "World")
        return json.dumps({"success": True, "greeting": f"Hello, {name}!"})

    ctx.register_tool(
        name="hello_world",
        toolset="hello_world",
        schema=schema,
        handler=handle_hello,
        description="Return a friendly greeting for the given name.",
    )

    # --- Hook: log every tool call ---
    def on_tool_call(tool_name, params, result):
        print(f"[hello-world] tool called: {tool_name}")

    ctx.register_hook("post_tool_call", on_tool_call)

Поместите оба файла в ~/.hermes/plugins/hello-world/, перезапустите Hermes, и модель сможет сразу вызывать hello_world. Hook будет выводить строку лога после каждого вызова инструмента.

Локальные плагины проекта в ./.hermes/plugins/ отключены по умолчанию. Включайте их только для доверенных репозиториев, установив HERMES_ENABLE_PROJECT_PLUGINS=true перед запуском Hermes.

Что могут делать плагины

Каждый API ctx.* ниже доступен внутри функции register(ctx) плагина.

Возможность Как
Добавление инструментов ctx.register_tool(name=..., toolset=..., schema=..., handler=...)
Добавление хуков ctx.register_hook("post_tool_call", callback)
Добавление слеш-команд ctx.register_command(name, handler, description) — добавляет /name в CLI и gateway-сессиях
Запуск инструментов из команд ctx.dispatch_tool(name, args) — вызывает зарегистрированный инструмент с автоматически подключённым контекстом родительского агента
Добавление CLI-команд ctx.register_cli_command(name, help, setup_fn, handler_fn) — добавляет hermes <plugin> <subcommand>
Внедрение сообщений ctx.inject_message(content, role="user") — см. Injecting Messages
Поставка файлов данных Path(__file__).parent / "data" / "file.yaml"
Включение навыков ctx.register_skill(name, path) — пространство имён plugin:skill, загружается через skill_view("plugin:skill")
Проверка переменных окружения requires_env: [API_KEY] в plugin.yaml — запрашивается во время hermes plugins install
Распространение через pip [project.entry-points."hermes_agent.plugins"]
Регистрация gateway-платформы (Discord, Telegram, IRC, …) ctx.register_platform(name, label, adapter_factory, check_fn, ...) — см. Adding Platform Adapters
Регистрация бэкенда генерации изображений ctx.register_image_gen_provider(provider) — см. Image Generation Provider Plugins
Регистрация движка сжатия контекста ctx.register_context_engine(engine) — см. Context Engine Plugins
Регистрация бэкенда памяти Подкласс MemoryProvider в plugins/memory/<name>/__init__.py — см. Memory Provider Plugins (использует отдельную систему обнаружения)
Выполнение LLM-вызова от хоста ctx.llm.complete(...) / ctx.llm.complete_structured(...) — использует активную модель пользователя + аутентификацию для однократного completion с опциональной JSON-схемой валидации. См. Plugin LLM Access
Регистрация инференс-бэкенда (LLM-провайдера) register_provider(ProviderProfile(...)) в plugins/model-providers/<name>/__init__.py — см. Model Provider Plugins (использует отдельную систему обнаружения)

Обнаружение плагинов

Источник Путь Назначение
Встроенные <repo>/plugins/ Поставляются с Hermes — см. Built-in Plugins
Пользовательские ~/.hermes/plugins/ Личные плагины
Проектные .hermes/plugins/ Плагины для конкретного проекта (требуется HERMES_ENABLE_PROJECT_PLUGINS=true)
pip hermes_agent.plugins entry_points Распространяемые пакеты
Nix services.hermes-agent.extraPlugins / extraPythonPackages Декларативные установки NixOS — см. Nix Setup

Более поздние источники переопределяют более ранние при совпадении имён, поэтому пользовательский плагин с тем же именем, что и встроенный, заменяет его.

Подкатегории плагинов

Внутри каждого источника Hermes также распознаёт подкатегории каталогов, которые направляют плагины в специализированные системы обнаружения:

Подкаталог Содержимое Система обнаружения
plugins/ (root) Обычные плагины — инструменты, хуки, слеш-команды, CLI-команды, встроенные навыки PluginManager (kind: standalone or backend)
plugins/platforms/<name>/ Адаптеры gateway-каналов (ctx.register_platform()) PluginManager (kind: platform, one level deeper)
plugins/image_gen/<name>/ Бэкенды генерации изображений (ctx.register_image_gen_provider()) PluginManager (kind: backend, one level deeper)
plugins/memory/<name>/ Провайдеры памяти (подкласс MemoryProvider) Собственный загрузчик в plugins/memory/__init__.py (kind: exclusive — один активный за раз)
plugins/context_engine/<name>/ Движки сжатия контекста (ctx.register_context_engine()) Собственный загрузчик в plugins/context_engine/__init__.py (один активный за раз)
plugins/model-providers/<name>/ Профили LLM-провайдеров (register_provider(ProviderProfile(...))) Собственный загрузчик в providers/__init__.py (ленивое сканирование при первом вызове get_provider_profile())

Пользовательские плагины в ~/.hermes/plugins/model-providers/<name>/ и ~/.hermes/plugins/memory/<name>/ переопределяют встроенные плагины с тем же именем — последний записавший побеждает в register_provider() / register_memory_provider(). Поместите каталог, и он заменит встроенный без каких-либо изменений в репозитории.

Плагины подключаются добровольно (с некоторыми исключениями)

Обычные плагины и установленные пользователем бэкенды отключены по умолчанию — обнаружение находит их (поэтому они отображаются в hermes plugins и /plugins), но ни один из них с хуками или инструментами не загружается, пока вы не добавите имя плагина в plugins.enabled в ~/.hermes/config.yaml. Это предотвращает выполнение стороннего кода без вашего явного согласия.

plugins:
  enabled:
    - my-tool-plugin
    - disk-cleanup
  disabled:       # optional deny-list — always wins if a name appears in both
    - noisy-plugin

Три способа изменить состояние:

hermes plugins                    # interactive toggle (space to check/uncheck)
hermes plugins enable <name>      # add to allow-list
hermes plugins disable <name>     # remove from allow-list + add to disabled

После hermes plugins install owner/repo вас спросят Enable 'name' now? [y/N] — по умолчанию нет. Пропустите запрос для скриптовых установок с помощью --enable или --no-enable.

Что не контролирует список разрешений

Некоторые категории плагинов обходят plugins.enabled — они являются частью встроенной поверхности Hermes, и базовая функциональность была бы нарушена, если бы они были отключены по умолчанию:

Тип плагина Как активируется вместо этого
Встроенные platform-плагины (IRC, Teams и т.д. в plugins/platforms/) Автоматически загружаются, чтобы каждый поставляемый gateway-канал был доступен. Фактический канал включается через gateway.platforms.<name>.enabled в config.yaml.
Встроенные бэкенды (image-gen провайдеры в plugins/image_gen/ и т.д.) Автоматически загружаются, чтобы бэкенд по умолчанию «просто работал». Выбор происходит через <category>.provider в config.yaml (например, image_gen.provider: openai).
Memory providers (plugins/memory/) Все обнаружены; активен ровно один, выбранный через memory.provider в config.yaml.
Context engines (plugins/context_engine/) Все обнаружены; активен один, выбранный через context.engine в config.yaml.
Model providers (plugins/model-providers/) Все встроенные провайдеры в plugins/model-providers/ обнаруживаются и регистрируются при первом вызове get_provider_profile(). Пользователь выбирает один из них через --provider или config.yaml.
Pip-installed backend plugins Подключаются через plugins.enabled (как обычные плагины).
Установленные пользователем платформы~/.hermes/plugins/platforms/) Подключаются через plugins.enabled — сторонние gateway-адаптеры требуют явного согласия.

Коротко: встроенная инфраструктура загружается автоматически; сторонние обычные плагины подключаются добровольно. Список разрешений plugins.enabled — это шлюз специально для произвольного кода, который пользователь помещает в ~/.hermes/plugins/.

Миграция для существующих пользователей

Когда вы обновляетесь до версии Hermes с добровольным подключением плагинов (схема конфигурации v21+), все пользовательские плагины, уже установленные в ~/.hermes/plugins/ и не находившиеся в plugins.disabled, автоматически переносятся в plugins.enabled. Ваша существующая настройка продолжает работать. Встроенные отдельные плагины НЕ переносятся — даже существующие пользователи должны явно подключить их. (Встроенным platform/backend-плагинам перенос никогда не требовался, поскольку они никогда не были заблокированы.)

Доступные хуки

Плагины могут регистрировать обратные вызовы для этих событий жизненного цикла. Подробную информацию, сигнатуры обратных вызовов и примеры см. на странице Event Hooks.

Hook Срабатывает когда
pre_tool_call Перед выполнением любого инструмента
post_tool_call После возврата любого инструмента
pre_llm_call Один раз за ход, перед LLM-циклом — может вернуть {"context": "..."} для внедрения контекста в сообщение пользователя
post_llm_call Один раз за ход, после LLM-цикла (только успешные ходы)
on_session_start Создана новая сессия (только первый ход)
on_session_end Конец каждого вызова run_conversation + обработчик выхода CLI
on_session_finalize CLI/gateway завершает активную сессию (/new, GC, выход из CLI)
on_session_reset Gateway заменяет ключ сессии (/new, /reset, /clear, ротация при простое)
subagent_stop Один раз для каждого дочернего агента после завершения delegate_task
pre_gateway_dispatch Gateway получил сообщение пользователя, перед аутентификацией + отправкой. Верните {"action": "skip" | "rewrite" | "allow", ...} для влияния на поток.

Типы плагинов

Hermes имеет четыре типа плагинов:

Тип Что делает Выбор Расположение
Обычные плагины Добавление инструментов, хуков, слеш-команд, CLI-команд Множественный (включить/отключить) ~/.hermes/plugins/
Memory providers Замена или расширение встроенной памяти Одиночный (один активный) plugins/memory/
Context engines Замена встроенного компрессора контекста Одиночный (один активный) plugins/context_engine/
Model providers Объявление инференс-бэкенда (OpenRouter, Anthropic, …) Множественная регистрация, выбор через --provider / config.yaml plugins/model-providers/

Memory providers и Context engines — это provider-плагины — только один каждого типа может быть активен одновременно. Model providers также являются плагинами, но загружаются одновременно; пользователь выбирает один из них через --provider или config.yaml. Обычные плагины можно включать в любой комбинации.

Подключаемые интерфейсы — куда обратиться для каждого

Таблица выше показывает четыре категории плагинов, но внутри «Обычных плагинов» PluginContext предоставляет несколько различных точек расширения — и Hermes также принимает расширения вне системы Python-плагинов (бэкенды на основе конфигурации, команды с shell-хуками, внешние серверы и т.д.). Используйте эту таблицу, чтобы найти правильную документацию для того, что вы хотите создать:

Хотите добавить… Как Руководство
Инструмент, который может вызывать LLM Python plugin — ctx.register_tool() Build a Hermes Plugin · Adding Tools
Lifecycle-хук (pre/post LLM, начало/конец сессии, фильтр инструментов) Python plugin — ctx.register_hook() Hooks reference · Build a Hermes Plugin
Слеш-команду для CLI / gateway Python plugin — ctx.register_command() Build a Hermes Plugin · Extending the CLI
Подкоманду для hermes <thing> Python plugin — ctx.register_cli_command() Extending the CLI
Навык, который поставляется с вашим плагином Python plugin — ctx.register_skill() Creating Skills
Инференс-бэкенд (LLM-провайдер: OpenAI-compat, Codex, Anthropic-Messages, Bedrock) Provider plugin — register_provider(ProviderProfile(...)) в plugins/model-providers/<name>/ Model Provider Plugins · Adding Providers
Gateway-канал (Discord / Telegram / IRC / Teams / и т.д.) Platform plugin — ctx.register_platform() в plugins/platforms/<name>/ Adding Platform Adapters
Бэкенд памяти (Honcho, Mem0, Supermemory, …) Memory plugin — подкласс MemoryProvider в plugins/memory/<name>/ Memory Provider Plugins
Стратегию сжатия контекста Context-engine plugin — ctx.register_context_engine() Context Engine Plugins
Бэкенд генерации изображений (DALL·E, SDXL, …) Backend plugin — ctx.register_image_gen_provider() Image Generation Provider Plugins
TTS-бэкенд (любая CLI — Piper, VoxCPM, Kokoro, xtts, скрипты клонирования голоса, …) На основе конфигурации — объявите в tts.providers.<name> с type: command в config.yaml TTS setup
STT-бэкенд (пользовательский whisper binary, локальная ASR CLI) На основе конфигурации — установите переменную окружения HERMES_LOCAL_STT_COMMAND как shell-шаблон Voice Message Transcription (STT)
Внешние инструменты через MCP (файловая система, GitHub, Linear, Notion, любой MCP-сервер) На основе конфигурации — объявите mcp_servers.<name> с command: / url: в config.yaml. Hermes автоматически обнаруживает инструменты сервера и регистрирует их вместе со встроенными. MCP
Дополнительные источники навыков (пользовательские GitHub-репозитории, частные индексы навыков) CLI — hermes skills tap add <repo> Skills Hub · Publishing a custom tap
Gateway event hooks (срабатывают на gateway:startup, session:start, agent:end, command:*) Поместите HOOK.yaml + handler.py в ~/.hermes/hooks/<name>/ Event Hooks
Shell-хуки (выполнение shell-команды при событиях — уведомления, журналы аудита, оповещения рабочего стола) На основе конфигурации — объявите в hooks: в config.yaml Shell Hooks
Не всё является Python-плагином. Некоторые поверхности расширения намеренно используют **команды оболочки на основе конфигурации** (TTS, STT, shell-хуки), так что любая CLI, которая у вас уже есть, становится плагином без написания Python. Другие — это **внешние серверы** (MCP), к которым агент подключается и автоматически регистрирует инструменты. А некоторые — это **каталоги для размещения** (gateway-хуки) со своим собственным форматом манифеста. Выберите правильную поверхность для стиля интеграции, подходящего вашему случаю; руководства по созданию в таблице выше охватывают заполнители, обнаружение и примеры.

Декларативные плагины NixOS

На NixOS плагины можно установить декларативно через опции модуля — без hermes plugins install. Подробности см. в Nix Setup guide.

services.hermes-agent = {
  # Directory plugin (source tree with plugin.yaml)
  extraPlugins = [ (pkgs.fetchFromGitHub { ... }) ];
  # Entry-point plugin (pip package)
  extraPythonPackages = [ (pkgs.python312Packages.buildPythonPackage { ... }) ];
  # Enable in config
  settings.plugins.enabled = [ "my-plugin" ];
};

Декларативные плагины добавляются с префиксом nix-managed- — они сосуществуют с плагинами, установленными вручную, и автоматически удаляются при исключении из конфигурации Nix.

Управление плагинами

hermes plugins                               # unified interactive UI
hermes plugins list                          # table: enabled / disabled / not enabled
hermes plugins install user/repo             # install from Git, then prompt Enable? [y/N]
hermes plugins install user/repo --enable    # install AND enable (no prompt)
hermes plugins install user/repo --no-enable # install but leave disabled (no prompt)
hermes plugins update my-plugin              # pull latest
hermes plugins remove my-plugin              # uninstall
hermes plugins enable my-plugin              # add to allow-list
hermes plugins disable my-plugin             # remove from allow-list + add to disabled

Интерактивный интерфейс

Запуск hermes plugins без аргументов открывает составной интерактивный экран:

Plugins
  ↑↓ navigate  SPACE toggle  ENTER configure/confirm  ESC done

  General Plugins
  [] my-tool-plugin  Custom search tool
   [ ] webhook-notifier  Event hooks
   [ ] disk-cleanup  Auto-cleanup of ephemeral files [bundled]

  Provider Plugins
     Memory Provider           honcho
     Context Engine            compressor

Выбор provider-плагинов сохраняется в config.yaml:

memory:
  provider: "honcho"      # empty string = built-in only

context:
  engine: "compressor"    # default built-in compressor

Включено, отключено или не выбрано

Плагины находятся в одном из трёх состояний:

Состояние Значение В plugins.enabled? В plugins.disabled?
enabled Загрузится при следующей сессии Да Нет
disabled Явно отключён — не загрузится, даже если также указан в enabled (неважно) Да
not enabled Обнаружен, но не подключён Нет Нет

По умолчанию для нового или встроенного плагина — not enabled. hermes plugins list показывает все три различных состояния, чтобы вы могли видеть, что было явно отключено, а что просто ожидает включения.

В запущенной сессии /plugins показывает, какие плагины в данный момент загружены.

Внедрение сообщений

Плагины могут внедрять сообщения в активную беседу с помощью ctx.inject_message():

ctx.inject_message("New data arrived from the webhook", role="user")

Signature: ctx.inject_message(content: str, role: str = "user") -> bool

Как это работает:

Это позволяет таким плагинам, как пульты дистанционного управления, мосты обмена сообщениями или приёмники webhook, передавать сообщения в беседу из внешних источников.

`inject_message` доступен только в режиме CLI. В gateway-режиме нет CLI-ссылки, и метод возвращает `False`.

См. полное руководство для ознакомления с контрактами обработчиков, форматом схемы, поведением хуков, обработкой ошибок и типичными ошибками.