---
url: /ru/guides/hooks.md
---
# Хуки Bot

Хуки позволяют Bot выполнять небольшие правила автоматизации вокруг инструментов, ходов разговора, памяти, активности рабочего пространства, подтверждений, сжатия контекста и субагентов. Они настраиваются для каждого Bot в файле рабочего пространства:

```text
/data/.memoh/hooks.json
```

Откройте страницу **Detail Page** нужного Bot и перейдите на вкладку **Hooks**, чтобы редактировать этот файл из UI.

***

## Вкладка Hooks

Вкладка **Hooks** — это JSON-редактор конфигурации хуков Bot. Она умеет:

* показывать, существует ли `/data/.memoh/hooks.json`
* показывать, включена ли пользовательская конфигурация
* считать включённые хуки и действия
* выводить каталог поддерживаемых событий
* показывать, какие события подключены к среде выполнения
* перезагружать и сохранять JSON-конфигурацию
* вставлять стартовый шаблон
* прогонять синтетическое событие через действующую конфигурацию хуков

Если файла нет, UI и сервис создают пустую включённую конфигурацию:

```json
{
  "version": 1,
  "enabled": true,
  "hooks": []
}
```

Визуального конструктора правил на вкладке нет. Редактируйте JSON напрямую.

***

## Структура конфигурации

```json
{
  "version": 1,
  "enabled": true,
  "defaults": {
    "timeout": "10s",
    "on_error": "fail",
    "max_output_bytes": 65536,
    "trigger_nested_hooks": false
  },
  "env": {
    "HOOK_LOG": "/data/.memoh/hooks.log"
  },
  "hooks": [
    {
      "name": "review shell commands",
      "event": "PreToolUse",
      "matcher": "^exec$",
      "enabled": true,
      "priority": 10,
      "actions": [
        {
          "type": "command",
          "command": "python3 /data/.memoh/review-command.py",
          "timeout": "5s",
          "on_error": "block"
        }
      ]
    }
  ]
}
```

Поля верхнего уровня:

| Поле | Описание |
|-------|-------------|
| `version` | Обязательная версия схемы. Текущая версия — `1`. |
| `enabled` | Включает или выключает хуки в этой пользовательской конфигурации. По умолчанию `true`. |
| `defaults.timeout` | Таймаут действия по умолчанию. Принимает длительности в стиле Go, такие как `10s`, или целое число секунд. По умолчанию `10s`. |
| `defaults.on_error` | Поведение при ошибке по умолчанию: `ignore`, `fail` или `block`. По умолчанию `fail`. |
| `defaults.max_output_bytes` | Максимум захватываемых байт stdout/stderr на одно действие типа command. По умолчанию `65536`. |
| `defaults.trigger_nested_hooks` | Разбирается схемой, по умолчанию `false`; отдельного элемента управления в UI хуков пока нет. |
| `env` | Дополнительные переменные окружения для действий типа command из пользовательской конфигурации. |
| `hooks` | Упорядоченный список правил. Сработавшие хуки выполняются по убыванию `priority`; при равном приоритете сохраняется порядок в файле. |

Поля хука:

| Поле | Описание |
|-------|-------------|
| `name` | Необязательное имя для отображения и отладки. |
| `event` | Обязательное имя события из каталога. |
| `matcher` | Необязательное регулярное выражение. Сопоставляется с наиболее подходящим целевым текстом запроса. |
| `enabled` | Включает или выключает этот хук. По умолчанию `true`. |
| `priority` | Большие числа выполняются первыми. |
| `actions` | Действия, выполняемые при срабатывании хука. |
| `conditions` | Присутствует в схеме для будущего расширения; сейчас при сопоставлении используются `event`, `enabled` и `matcher`. |

Цель для `matcher` выбирается из запроса хука в таком порядке:

* `tool.name`
* `approval.tool_name`
* `channel.platform`
* `memory.scope`
* `extra.command`, `extra.path`, `extra.operation` или `extra.scope`
* имя события

***

## Типы действий

Поддерживаются два типа действий: `command` и `tool`.

### Действие command

```json
{
  "type": "command",
  "command": "mkdir -p .memoh && cat >> .memoh/hooks.log",
  "work_dir": "/data",
  "timeout": "10s",
  "on_error": "ignore"
}
```

Действие `command` выполняется внутри контейнера рабочего пространства Bot. Запрос хука передаётся как JSON на stdin, с завершающим переводом строки.

Рабочий каталог определяется так:

1. `action.work_dir`
2. текущий каталог рабочего пространства из запроса
3. `/data`

Переменные окружения включают:

* `env` верхнего уровня из действующей конфигурации
* `MEMOH_HOOK_EVENT`
* `MEMOH_HOOK_NAME`
* `MEMOH_BOT_ID`
* `MEMOH_SESSION_ID`

Если stdout — это JSON, команда может вернуть:

```json
{
  "decision": "append_context",
  "reason": "extra context added",
  "append_context": "Use the production-safe command variant.",
  "metadata": {
    "source": "hook"
  }
}
```

Если stdout — не JSON, Memoh трактует действие как `allow` и сохраняет «сырой» stdout в метаданных действия. Ненулевой код выхода — это ошибка действия.

### Действие tool

```json
{
  "type": "tool",
  "tool": "record_event",
  "input": {
    "source": "hook"
  },
  "timeout": "10s",
  "on_error": "fail"
}
```

Действие `tool` вызывает доступный инструмент Bot по имени с настроенным `input`. Результаты инструмента могут вернуть `decision`, `reason` и `append_context` в объектном результате.

`mcp_tool` зарезервирован в кодовой базе, но сейчас отклоняется.

***

## Решения и ошибки

Действия могут возвращать одно из таких решений:

| Решение | Эффект |
|----------|--------|
| `allow` | Продолжить как обычно. |
| `deny` | Запретить охраняемую операцию. Для `PreToolUse` это отклоняет вызов инструмента. |
| `ask_approval` | Запросить подтверждение человека там, где среда выполнения поддерживает передачу на подтверждение. |
| `append_context` | Добавить контекст там, где интеграция события потребляет `append_context`, например в потоках, связанных с промптом, моделью или памятью. |

`on_error` управляет тем, что происходит при сбое действия:

| Значение | Эффект |
|-------|--------|
| `ignore` | Записать в лог и перейти к следующему действию. |
| `fail` | Вернуть ошибку действия. Это значение по умолчанию. |
| `block` | Превратить сбой в решение `deny`. |

***

## Каталог событий

Вкладка **Hooks** загружает каталог событий из `/bots/{bot_id}/hooks/events`. События, помеченные как поддерживаемые средой выполнения, подключены к текущим путям исполнения. События «только в каталоге» принимаются разбором конфигурации и тестовыми запусками, но живой путь среды выполнения их пока не порождает.

| Событие | Область | Поддержано средой выполнения | Примечания |
|-------|------|-------------------|-------|
| `PreToolUse` | Инструменты | Да | Выполняется до решения о подтверждении вызова инструмента. Может запретить или запросить подтверждение. |
| `PostToolUse` | Инструменты | Да | Выполняется после успешного вызова инструмента. |
| `ToolError` | Инструменты | Да | Выполняется, когда вызов инструмента возвращает ошибку. |
| `SessionStart` | Сессия | Да | Выполняется после создания сессии. |
| `UserMessageReceived` | Разговор | Да | Выполняется после того, как резолвер разговора получил входящее сообщение пользователя. |
| `BeforePromptBuild` | Промпт | Да | Выполняется до сборки промпта; `append_context` может добавляться в системный промпт. |
| `AfterPromptBuild` | Промпт | Да | Выполняется после сборки промпта; `append_context` может добавляться в системный промпт. |
| `BeforeModelCall` | Модель | Да | Выполняется перед шагами генерации модели; `append_context` может добавляться как сообщение пользователя. |
| `AfterModelCall` | Модель | Да | Выполняется после шагов генерации модели. |
| `TurnEnd` | Ход | Да | Выполняется по завершении хода. |
| `TurnError` | Ход | Да | Выполняется при сбое хода. |
| `BeforeMemorySearch` | Память | Да | Выполняется перед поиском в памяти. |
| `AfterMemorySearch` | Память | Да | Выполняется после поиска в памяти; `append_context` может вливаться в контекст памяти. |
| `BeforeMemoryWrite` | Память | Да | Выполняется перед записью памяти разговора. |
| `AfterMemoryWrite` | Память | Да | Выполняется после записи памяти. |
| `MemoryExtracted` | Память | Да | Выполняется после извлечения памяти и подготовки записи. |
| `WorkspaceStart` | Рабочее пространство | Да | Выполняется после запуска рабочего пространства. |
| `WorkspaceStop` | Рабочее пространство | Да | Выполняется при остановке рабочего пространства. |
| `BeforeWorkspaceCommand` | Рабочее пространство | Да | Выполняется перед shell-командами рабочего пространства. Может запретить команду. |
| `AfterWorkspaceCommand` | Рабочее пространство | Да | Выполняется после shell-команд рабочего пространства. |
| `BeforeFileWrite` | Рабочее пространство | Да | Выполняется перед записью файлов и патчами. Может запретить запись. |
| `AfterFileWrite` | Рабочее пространство | Да | Выполняется после записи файлов и патчей. |
| `BeforeApprovalCreate` | Подтверждения | Да | Выполняется перед созданием запроса на подтверждение инструмента. |
| `ApprovalRequested` | Подтверждения | Да | Выполняется после того, как подтверждение запрошено. |
| `ApprovalResolved` | Подтверждения | Да | Выполняется после того, как по подтверждению принято решение. |
| `ApprovalTimeout` | Подтверждения | Да | Выполняется, когда подтверждение истекает по таймауту. |
| `PreCompact` | Сжатие | Да | Выполняется перед сжатием сессии. |
| `PostCompact` | Сжатие | Да | Выполняется после сжатия сессии. |
| `SubagentStart` | Субагенты | Да | Выполняется перед запуском задачи субагента. |
| `SubagentStop` | Субагенты | Да | Выполняется после остановки задачи субагента. |
| `InboundMessageNormalized` | Сообщения | Нет | Пока только в каталоге. |
| `BeforeOutboundMessage` | Сообщения | Нет | Пока только в каталоге. |
| `AfterOutboundMessage` | Сообщения | Нет | Пока только в каталоге. |
| `ChannelDeliveryFailed` | Сообщения | Нет | Пока только в каталоге. |

***

## Тестирование хуков

Используйте раздел **Test** на вкладке **Hooks**, чтобы прогнать синтетическое событие:

1. Выберите событие.
2. Отредактируйте JSON-нагрузку.
3. Нажмите **Run Test**.
4. Изучите возвращённый результат: сработавшие хуки, выполненные действия, решение, результаты действий и метаданные источника хуков.

Тестовый путь использует действующую конфигурацию и выполняет настоящие действия. Не включайте в тестовые нагрузки разрушительные команды и вызовы инструментов — если только это не то, что вы намерены проверить.

***

## Замечания о безопасности

Хуки выполняются внутри рабочего пространства Bot. Относитесь к ним как к любому другому коду, который там работает.

* Просматривайте каждое действие типа command перед включением.
* Будьте осторожны с `PreToolUse`, `BeforeWorkspaceCommand` и `BeforeFileWrite`: они могут заблокировать нормальную работу Bot.
* Держите таймауты короткими и задавайте `on_error` осознанно.
* Не храните долгоживущие секреты прямо в `hooks.json`.
* Для рискованных хуков предпочитайте узкие выражения `matcher`.
* Помните, что действия типа command получают запрос хука на stdin, а в нём могут быть текст сообщений, входные данные инструментов, пути и ошибки.

***

## Связанные страницы

* [Работа с Bot](./working-with-bots.md)
* [Навыки](./skills.md)
