agent-sdk/hooks.md +64 −64
15* **Отслеживать жизненный цикл сеанса** для управления состоянием, очистки ресурсов или отправки уведомлений15* **Отслеживать жизненный цикл сеанса** для управления состоянием, очистки ресурсов или отправки уведомлений
16 16
17<h2 id="how-hooks-work">17<h2 id="how-hooks-work">
1818 Как работают hooks Как работают хуки
19</h2>19</h2>
20 20
21<Steps>21<Steps>
22 <Step title="Срабатывает событие">22 <Step title="Срабатывает событие">
2323 Что-то происходит во время выполнения агента, и SDK срабатывает событие: инструмент вот-вот будет вызван (`PreToolUse`), инструмент вернул результат (`PostToolUse`), подагент запустился или остановился, агент неактивен или выполнение завершилось. См. [полный список событий](#available-hooks). Во время выполнения агента что-то происходит, и SDK генерирует событие: инструмент вот-вот будет вызван (`PreToolUse`), инструмент вернул результат (`PostToolUse`), субагент запустился или остановился, агент простаивает или выполнение завершилось. См. [полный список событий](#available-hooks).
24 </Step>24 </Step>
25 25
2626 <Step title="SDK собирает зарегистрированные hooks"> <Step title="SDK собирает зарегистрированные хуки">
2727 SDK проверяет наличие hooks, зарегистрированных для этого типа события. Это включает callback hooks, которые вы передаете в `options.hooks`, и hooks команд shell из файлов настроек, когда соответствующая запись [`settingSources`](/docs/ru/agent-sdk/typescript#settingsource) или [`setting_sources`](/docs/ru/agent-sdk/python#settingsource) включена, что она есть для параметров `query()` по умолчанию. SDK проверяет наличие хуков, зарегистрированных для этого типа события. Сюда входят callback-хуки, которые вы передаете в `options.hooks`, и хуки shell-команд из файлов настроек, если включена соответствующая запись [`settingSources`](/docs/ru/agent-sdk/typescript#settingsource) или [`setting_sources`](/docs/ru/agent-sdk/python#settingsource), что по умолчанию так и есть для параметров `query()`.
28 </Step>28 </Step>
29 29
3030 <Step title="Matchers фильтруют, какие hooks запускаются"> <Step title="Фильтрация запускаемых хуков с помощью matcher">
3131 Если hook имеет паттерн [`matcher`](#matchers) (например, `"Write|Edit"`), SDK проверяет его против цели события (например, имя инструмента). Hooks без matcher запускаются для каждого события этого типа. Если у хука есть паттерн [`matcher`](#matchers) (например, `"Write|Edit"`), SDK проверяет его на соответствие цели события (например, имени инструмента). Хуки без matcher запускаются для каждого события этого типа.
32 </Step>32 </Step>
33 33
34 <Step title="Выполняются функции обратного вызова">34 <Step title="Выполняются функции обратного вызова">
3535 Каждая функция [обратного вызова](#callback-functions) matching hook получает информацию о том, что происходит: имя инструмента, его аргументы, ID сеанса и другие детали, специфичные для события. [Функция обратного вызова](#callback-functions) каждого подходящего хука получает информацию о том, что происходит: имя инструмента, его аргументы, ID сессии и другие детали, специфичные для события.
36 </Step>36 </Step>
37 37
38 <Step title="Ваш callback возвращает решение">38 <Step title="Ваш callback возвращает решение">
3939 После выполнения любых операций (логирование, вызовы API, валидация), ваш callback возвращает [объект вывода](#outputs), который говорит агенту, что делать: разрешить операцию, заблокировать ее, изменить входные данные или внедрить контекст в разговор. После выполнения любых операций (логирование, вызовы API, валидация) ваш callback возвращает [объект вывода](#outputs), который сообщает агенту, что делать: разрешить операцию, заблокировать ее, изменить входные данные или внедрить контекст в диалог.
40 </Step>40 </Step>
41</Steps>41</Steps>
42 42
4343Следующий пример объединяет эти шаги. Он регистрирует hook `PreToolUse` (шаг 1) с matcher `"Write|Edit"` (шаг 3), поэтому callback срабатывает только для инструментов записи файлов. При срабатывании callback получает входные данные инструмента (шаг 4), проверяет, нацелена ли путь файла на файл `.env`, и возвращает `permissionDecision: "deny"` для блокировки операции (шаг 5):Следующий пример объединяет эти шаги. Он регистрирует хук `PreToolUse` (шаг 1) с matcher `"Write|Edit"` (шаг 3), поэтому callback срабатывает только для инструментов записи файлов. При срабатывании callback получает входные данные инструмента (шаг 4), проверяет, указывает ли путь файла на файл `.env`, и возвращает `permissionDecision: "deny"` для блокировки операции (шаг 5):
44 44
45<CodeGroup>45<CodeGroup>
46 ```python Python theme={null}46 ```python Python theme={null}
140 ```140 ```
141</CodeGroup>141</CodeGroup>
142 142
143143Когда вы запустите любой из скриптов, Claude попытается создать файл `.env`, hook заблокирует вызов инструмента, и финальный ответ Claude объяснит, что он не может создавать файлы `.env`.Когда вы запустите любой из скриптов, Claude попытается создать файл `.env`, и хук отклонит вызов инструмента.
144 144
145<h2 id="available-hooks">145<h2 id="available-hooks">
146 Доступные hooks146 Доступные hooks
179| `ConfigChange` | Нет | Да | Файл конфигурации изменился | Динамически перезагрузить настройки |179| `ConfigChange` | Нет | Да | Файл конфигурации изменился | Динамически перезагрузить настройки |
180| `InstructionsLoaded` | Нет | Да | Файл `CLAUDE.md` или файл правил загружается в контекст | Проверять, какие файлы инструкций загружаются |180| `InstructionsLoaded` | Нет | Да | Файл `CLAUDE.md` или файл правил загружается в контекст | Проверять, какие файлы инструкций загружаются |
181| `WorktreeCreate` | Нет | Да | Git worktree создан | Отслеживать изолированные рабочие пространства |181| `WorktreeCreate` | Нет | Да | Git worktree создан | Отслеживать изолированные рабочие пространства |
182182| `WorktreeRemove` | Нет | Да | Git worktree удален | Очистить ресурсы рабочего пространства || `WorktreeRemove` | Нет | Да | Удаляется worktree, созданный хуком `WorktreeCreate` | Очистить ресурсы рабочего пространства |
183| `CwdChanged` | Нет | Да | Рабочий каталог изменяется во время сеанса | Перезагрузить переменные окружения для каждого каталога |183| `CwdChanged` | Нет | Да | Рабочий каталог изменяется во время сеанса | Перезагрузить переменные окружения для каждого каталога |
184| `FileChanged` | Нет | Да | Отслеживаемый файл изменяется, создаётся или удаляется | Перезагрузить конфигурацию при изменении файлов проекта |184| `FileChanged` | Нет | Да | Отслеживаемый файл изменяется, создаётся или удаляется | Перезагрузить конфигурацию при изменении файлов проекта |
185| `DirectoryAdded` | Нет | Да | Рабочий каталог добавляется во время сеанса | Установить зависимости для репозитория, добавленного во время сеанса |185| `DirectoryAdded` | Нет | Да | Рабочий каталог добавляется во время сеанса | Установить зависимости для репозитория, добавленного во время сеанса |
186 186
187<h2 id="configure-hooks">187<h2 id="configure-hooks">
188188 Настройка hooks Настройка хуков
189</h2>189</h2>
190 190
191191Чтобы настроить hook, передайте его в поле `hooks` ваших параметров агента (`ClaudeAgentOptions` в Python, объект `options` в TypeScript). Этот фрагмент предполагает, что вы уже определили callback hook, например `protect_env_files` в Python или `protectEnvFiles` в TypeScript из примера выше:Чтобы настроить хук, передайте его в поле `hooks` ваших параметров агента (`ClaudeAgentOptions` в Python, объект `options` в TypeScript). Этот фрагмент предполагает, что вы уже определили callback хука, например `protect_env_files` в Python или `protectEnvFiles` в TypeScript из примера выше:
192 192
193<CodeGroup>193<CodeGroup>
194 ```python Python theme={null}194 ```python Python theme={null}
218 218
219Опция `hooks` — это словарь (Python) или объект (TypeScript), где:219Опция `hooks` — это словарь (Python) или объект (TypeScript), где:
220 220
221221* **Ключи**: [имена событий hook](#available-hooks), такие как `'PreToolUse'`, `'PostToolUse'` и `'Stop'`* **Ключи**: [имена событий хуков](#available-hooks), такие как `'PreToolUse'`, `'PostToolUse'` и `'Stop'`
222* **Значения**: массивы [matchers](#matchers), каждый содержащий необязательный паттерн фильтра и ваши [функции обратного вызова](#callback-functions)222* **Значения**: массивы [matchers](#matchers), каждый содержащий необязательный паттерн фильтра и ваши [функции обратного вызова](#callback-functions)
223 223
224<h3 id="matchers">224<h3 id="matchers">
225 Matchers225 Matchers
226</h3>226</h3>
227 227
228228Используйте matchers для фильтрации, когда срабатывают ваши callbacks. Поле `matcher` соответствует другому значению в зависимости от типа события hook. Например, hooks на основе инструментов соответствуют имени инструмента, в то время как hooks `Notification` соответствуют типу уведомления.Используйте matchers для фильтрации, когда срабатывают ваши callbacks. Поле `matcher` сопоставляется с разными значениями в зависимости от типа события хука. Например, хуки на основе инструментов сопоставляются с именем инструмента, в то время как хуки `Notification` сопоставляются с типом уведомления.
229 229
230SDK matchers следуют тем же правилам, что и [matchers в файлах настроек](/docs/ru/hooks#matcher-patterns). Этот раздел документирует пути оценки точной строки и регулярного выражения, требования к версиям и значения matcher для каждого типа события.230SDK matchers следуют тем же правилам, что и [matchers в файлах настроек](/docs/ru/hooks#matcher-patterns). Этот раздел документирует пути оценки точной строки и регулярного выражения, требования к версиям и значения matcher для каждого типа события.
231 231
232| Опция | Тип | По умолчанию | Описание |232| Опция | Тип | По умолчанию | Описание |
233| - | - | - | - |233| - | - | - | - |
234234| `matcher` | `string` | `undefined` | Паттерн, сопоставляемый с полем фильтра события, следуя [правилам для matchers в файлах настроек](/docs/ru/hooks#matcher-patterns). Для hooks инструментов это имя инструмента. Встроенные инструменты включают `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`, `Agent` и другие (см. [Tool Input Types](/docs/ru/agent-sdk/typescript#tool-input-types) для полного списка). MCP инструменты используют паттерн `mcp__<server>__<action>`, где `<server>` — это ключ, который вы используете в конфигурации `mcpServers`. || `matcher` | `string` | `undefined` | Паттерн, сопоставляемый с полем фильтра события, следуя [правилам для matchers в файлах настроек](/docs/ru/hooks#matcher-patterns). Для хуков инструментов это имя инструмента. Встроенные инструменты включают `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`, `Agent` и другие (см. [Tool Input Types](/docs/ru/agent-sdk/typescript#tool-input-types) для полного списка). MCP инструменты используют паттерн `mcp__<server>__<action>`, где `<server>` — это ключ, который вы используете в конфигурации `mcpServers`. |
235| `hooks` | `HookCallback[]` | - | Обязательно. Массив функций обратного вызова для выполнения, когда паттерн совпадает |235| `hooks` | `HookCallback[]` | - | Обязательно. Массив функций обратного вызова для выполнения, когда паттерн совпадает |
236236| `timeout` | `number` | `undefined` | Timeout в секундах. Если опущен, Claude Code применяет [timeout события по умолчанию](#hook-timeout). Ваши SDK callbacks следуют значениям по умолчанию hook `command` || `timeout` | `number` | `undefined` | Таймаут в секундах. Если опущен, Claude Code применяет [таймаут события по умолчанию](#hook-timeout). Ваши SDK callbacks следуют значениям по умолчанию хука `command` |
237 237
238238Используйте паттерн `matcher` для нацеливания на конкретные инструменты, когда это возможно. Matcher с `'Bash'` запускается только для команд Bash, в то время как опущение паттерна запускает ваши callbacks для каждого возникновения события. Опустите его намеренно для логирования каждого вызова инструмента, который делает ваш сеанс.Используйте паттерн `matcher` для нацеливания на конкретные инструменты, когда это возможно. Matcher с `'Bash'` запускается только для команд Bash, в то время как опущение паттерна запускает ваши callbacks для каждого возникновения события. Опустите его намеренно для логирования каждого вызова инструмента, который делает ваша сессия.
239 239
240<h3 id="callback-functions">240<h3 id="callback-functions">
241 Функции обратного вызова241 Функции обратного вызова
245 Входные данные245 Входные данные
246</h4>246</h4>
247 247
248248Каждый callback hook получает три аргумента:Каждый callback хука получает три аргумента:
249 249
250250* **Входные данные:** типизированный объект, содержащий детали события. Каждый тип hook имеет свою форму входных данных. Например, `PreToolUseHookInput` включает `tool_name` и `tool_input`, в то время как `NotificationHookInput` включает `message`. См. полные определения типов в справочниках [TypeScript](/docs/ru/agent-sdk/typescript#hookinput) и [Python](/docs/ru/agent-sdk/python#hookinput) SDK.* **Входные данные:** типизированный объект, содержащий детали события. Каждый тип хука имеет свою форму входных данных. Например, `PreToolUseHookInput` включает `tool_name` и `tool_input`, в то время как `NotificationHookInput` включает `message`. См. полные определения типов в справочниках [TypeScript](/docs/ru/agent-sdk/typescript#hookinput) и [Python](/docs/ru/agent-sdk/python#hookinput) SDK.
251251 * Все входные данные hook содержат `session_id`, `cwd` и `hook_event_name`. * Все входные данные хуков содержат `session_id`, `cwd` и `hook_event_name`.
252252 * `agent_id` и `agent_type` заполняются, когда hook срабатывает внутри подагента. В TypeScript они находятся на базовом входе hook и доступны для всех типов hook. В Python они являются необязательными полями на `PreToolUse`, `PostToolUse`, `PostToolUseFailure` и `PermissionRequest`, и обязательными полями на `SubagentStart` и `SubagentStop`. * `agent_id` и `agent_type` заполняются, когда хук срабатывает внутри субагента. В TypeScript они находятся на базовом входе хука и доступны для всех типов хуков. В Python они являются необязательными полями на `PreToolUse`, `PostToolUse`, `PostToolUseFailure` и `PermissionRequest`, и обязательными полями на `SubagentStart` и `SubagentStop`.
253* **ID использования инструмента** (`str | None` / `string | undefined`): коррелирует события `PreToolUse` и `PostToolUse` для одного и того же вызова инструмента.253* **ID использования инструмента** (`str | None` / `string | undefined`): коррелирует события `PreToolUse` и `PostToolUse` для одного и того же вызова инструмента.
254* **Контекст:** в TypeScript содержит свойство `signal` (`AbortSignal`) для отмены. В Python этот аргумент зарезервирован для будущего использования.254* **Контекст:** в TypeScript содержит свойство `signal` (`AbortSignal`) для отмены. В Python этот аргумент зарезервирован для будущего использования.
255 255
259 259
260Ваш callback возвращает объект с двумя категориями полей:260Ваш callback возвращает объект с двумя категориями полей:
261 261
262262* **Поля верхнего уровня** принимаются для каждого события: `systemMessage` показывает сообщение пользователю, и `continue` (`continue_` в Python) определяет, продолжает ли агент работать после этого hook. Некоторые события отбрасывают их или доставляют их в другое место. Раздел каждого [события](/docs/ru/hooks#hook-events) на странице hooks говорит, где они попадают.* **Поля верхнего уровня** принимаются для каждого события: `systemMessage` показывает сообщение пользователю, и `continue` (`continue_` в Python) определяет, продолжает ли агент работать после этого хука. Некоторые события отбрасывают их или доставляют их в другое место. Раздел каждого [события](/docs/ru/hooks#hook-events) на странице хуков говорит, где они попадают.
263* **`hookSpecificOutput`** контролирует текущую операцию. Поля, которые вы устанавливаете внутри, зависят от типа события хука:263* **`hookSpecificOutput`** контролирует текущую операцию. Поля, которые вы устанавливаете внутри, зависят от типа события хука:
264 * Для хуков `PreToolUse` здесь вы устанавливаете `permissionDecision` (`"allow"`, `"deny"`, `"ask"` или `"defer"`), `permissionDecisionReason` и `updatedInput`. Если вы вернете `"defer"`, ход завершается сообщением с результатом, у которого `stop_reason` равен `"tool_deferred"`, чтобы вы могли [возобновить вызов позже](/docs/ru/hooks#defer-a-tool-call-for-later).264 * Для хуков `PreToolUse` здесь вы устанавливаете `permissionDecision` (`"allow"`, `"deny"`, `"ask"` или `"defer"`), `permissionDecisionReason` и `updatedInput`. Если вы вернете `"defer"`, ход завершается сообщением с результатом, у которого `stop_reason` равен `"tool_deferred"`, чтобы вы могли [возобновить вызов позже](/docs/ru/hooks#defer-a-tool-call-for-later).
265265 * Для хуков `PostToolUse` вы можете установить `additionalContext` для добавления информации к результату инструмента. Чтобы заменить выходные данные инструмента перед тем, как Claude их увидит, установите `updatedToolOutput`, который работает для любого инструмента в обоих SDK. Более старое поле `updatedMCPToolOutput` заменяет только выходные данные MCP инструмента и является устаревшим. * Для хуков `PostToolUse` вы можете установить `additionalContext` для добавления информации к результату инструмента. Чтобы заменить выходные данные инструмента перед тем, как Claude их увидит, установите `updatedToolOutput`, который работает для любого инструмента в обоих SDK. Более старое поле `updatedMCPToolOutput` заменяет только выходные данные MCP инструмента.
266 * В TypeScript SDK callback `PostToolUse` может также возвращать `classifierContext`, краткую заметку о результате вызова инструмента для классификатора разрешений [авторежима](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode). Поскольку ваш callback работает в собственном процессе вашего приложения, классификатор может учитывать заявление пользователя, которое вы передаете в заметке, как намерение пользователя. Поле требует TypeScript Agent SDK версии 0.3.236 или позже. В разделе [Аннотирование результата для классификатора авторежима](/docs/ru/hooks#annotate-a-result-for-the-auto-mode-classifier) описаны ограничение по длине, правило только синхронного выполнения и то, что не следует помещать в заметку.266 * В TypeScript SDK callback `PostToolUse` может также возвращать `classifierContext`, краткую заметку о результате вызова инструмента для классификатора разрешений [авторежима](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode). Поскольку ваш callback работает в собственном процессе вашего приложения, классификатор может учитывать заявление пользователя, которое вы передаете в заметке, как намерение пользователя. Поле требует TypeScript Agent SDK версии 0.3.236 или позже. В разделе [Аннотирование результата для классификатора авторежима](/docs/ru/hooks#annotate-a-result-for-the-auto-mode-classifier) описаны ограничение по длине, правило только синхронного выполнения и то, что не следует помещать в заметку.
267 267
268268Возвращайте `{}` для разрешения операции без изменений. SDK callback hooks используют тот же формат вывода JSON, что и [hooks команд shell Claude Code](/docs/ru/hooks#json-output), который документирует каждое поле и опцию, специфичную для события. Для определений типов SDK см. справочники [TypeScript](/docs/ru/agent-sdk/typescript#synchookjsonoutput) и [Python](/docs/ru/agent-sdk/python#synchookjsonoutput) SDK.Возвращайте `{}` для разрешения операции без изменений. SDK callback-хуки используют тот же формат вывода JSON, что и [хуки shell-команд Claude Code](/docs/ru/hooks#json-output), который документирует каждое поле и опцию, специфичную для события. Для определений типов SDK см. справочники [TypeScript](/docs/ru/agent-sdk/typescript#synchookjsonoutput) и [Python](/docs/ru/agent-sdk/python#synchookjsonoutput) SDK.
269 269
270<Note>270<Note>
271271 Когда применяются несколько hooks или правил разрешений, `deny` имеет приоритет над `defer`, который имеет приоритет над `ask`, который имеет приоритет над `allow`. Если какой-либо hook возвращает `deny`, операция блокируется независимо от других hooks. Когда применяются несколько хуков или правил разрешений, `deny` имеет приоритет над `defer`, который имеет приоритет над `ask`, который имеет приоритет над `allow`. Если какой-либо хук возвращает `deny`, операция блокируется независимо от других хуков.
272</Note>272</Note>
273 273
274<h4 id="asynchronous-output">274<h4 id="asynchronous-output">
275 Асинхронный вывод275 Асинхронный вывод
276</h4>276</h4>
277 277
278278По умолчанию агент ждет, пока ваш hook вернется, прежде чем продолжить. Если ваш hook выполняет побочный эффект, такой как логирование или отправка webhook, и не нужно влиять на поведение агента, вы можете вернуть асинхронный вывод вместо этого. Это говорит агенту продолжить немедленно без ожидания завершения hook. В этом фрагменте `send_to_logging_service` в Python и `sendToLoggingService` в TypeScript служат заменой для любой функции логирования, которую вы определяете:По умолчанию агент ждет, пока ваш хук вернется, прежде чем продолжить. Если ваш хук выполняет побочный эффект, такой как логирование или отправка webhook, и ему не нужно влиять на поведение агента, вы можете вернуть асинхронный вывод вместо этого. Это говорит агенту продолжить немедленно без ожидания завершения хука. В этом фрагменте `send_to_logging_service` в Python и `sendToLoggingService` в TypeScript служат заменой для любой функции логирования, которую вы определяете:
279 279
280<CodeGroup>280<CodeGroup>
281 ```python Python theme={null}281 ```python Python theme={null}
297| Поле | Тип | Описание |297| Поле | Тип | Описание |
298| - | - | - |298| - | - | - |
299| `async` | `true` | Сигнализирует асинхронный режим. Агент продолжает без ожидания. В Python используйте `async_` для избежания зарезервированного ключевого слова. |299| `async` | `true` | Сигнализирует асинхронный режим. Агент продолжает без ожидания. В Python используйте `async_` для избежания зарезервированного ключевого слова. |
300300| `asyncTimeout` | `number` | Необязательный timeout в миллисекундах для фоновой операции || `asyncTimeout` | `number` | Необязательный таймаут в миллисекундах для фоновой операции |
301 301
302<Note>302<Note>
303 Асинхронные выходы не могут блокировать, изменять или внедрять контекст в операцию, так как агент уже продолжил. Используйте их только для побочных эффектов, таких как логирование, метрики или уведомления.303 Асинхронные выходы не могут блокировать, изменять или внедрять контекст в операцию, так как агент уже продолжил. Используйте их только для побочных эффектов, таких как логирование, метрики или уведомления.
798</h2>798</h2>
799 799
800<h3 id="hook-not-firing">800<h3 id="hook-not-firing">
801801 Hook не срабатывает Хук не срабатывает
802</h3>802</h3>
803 803
804804* Проверьте, что имя события hook правильное и чувствительно к регистру (`PreToolUse`, а не `preToolUse`)* Проверьте, что имя события хука правильное и чувствительно к регистру (`PreToolUse`, а не `preToolUse`)
805* Проверьте, что ваш паттерн matcher точно совпадает с именем инструмента805* Проверьте, что ваш паттерн matcher точно совпадает с именем инструмента
806806* Убедитесь, что hook находится под правильным типом события в `options.hooks`* Убедитесь, что хук находится под правильным типом события в `options.hooks`
807807* Для non-tool hooks, которые поддерживают matchers, таких как `Notification` и `SubagentStop`, matchers соответствуют разным полям, и `Stop` полностью игнорирует matchers (см. [matcher patterns](/docs/ru/hooks#matcher-patterns))* Для хуков, не связанных с инструментами, которые поддерживают matcher, таких как `Notification` и `SubagentStop`, matcher сопоставляется с другими полями, а `Stop` полностью игнорирует matcher (см. [паттерны matcher](/docs/ru/hooks#matcher-patterns))
808808* Hooks могут не срабатывать, когда агент достигает лимита [`max_turns`](/docs/ru/agent-sdk/python#claudeagentoptions), потому что сеанс заканчивается перед тем, как hooks смогут выполниться* Хуки могут не срабатывать, когда агент достигает лимита [`max_turns`](/docs/ru/agent-sdk/python#claudeagentoptions), потому что сессия заканчивается до того, как хуки смогут выполниться
809 809
810<h3 id="matcher-not-filtering-as-expected">810<h3 id="matcher-not-filtering-as-expected">
811 Matcher не фильтрует как ожидается811 Matcher не фильтрует как ожидается
812</h3>812</h3>
813 813
814814Matchers соответствуют только имени инструмента, а не путям файлов или другим аргументам. Для фильтрации по пути файла проверьте `tool_input.file_path` внутри вашего hook:Matcher сопоставляется только с именами инструментов, а не с путями файлов или другими аргументами. Для фильтрации по пути файла проверьте `tool_input.file_path` внутри вашего хука:
815 815
816```typescript theme={null}816```typescript theme={null}
817const myHook: HookCallback = async (input, toolUseID, { signal }) => {817const myHook: HookCallback = async (input, toolUseID, { signal }) => {
825```825```
826 826
827<h3 id="hook-timeout">827<h3 id="hook-timeout">
828828 Hook timeout Таймаут хука
829</h3>829</h3>
830 830
831831Claude Code запускает каждый callback с timeout, который вы устанавливаете в секундах с помощью поля `timeout` на его `HookMatcher`. Когда вы не устанавливаете его, Claude Code использует значение по умолчанию для события: 600 секунд для большинства событий, 30 секунд для `UserPromptSubmit`, `PreModelSwitch` и `PostModelSwitch`, и 10 секунд для `MessageDisplay`. Claude Code запускает callbacks `SessionEnd` во время завершения работы под более коротким [бюджетом timeout SessionEnd](/docs/ru/hooks#sessionend-input), 1,5 секунды по умолчанию.Claude Code запускает каждый callback с таймаутом, который вы устанавливаете в секундах с помощью поля `timeout` в его `HookMatcher`. Если вы его не устанавливаете, Claude Code использует значение по умолчанию для события: 600 секунд для большинства событий, 30 секунд для `UserPromptSubmit`, `PreModelSwitch` и `PostModelSwitch` и 10 секунд для `MessageDisplay`. Claude Code запускает callbacks `SessionEnd` во время завершения работы в рамках более короткого [бюджета таймаута SessionEnd](/docs/ru/hooks#sessionend-input), по умолчанию 1,5 секунды.
832 832
833833Когда callback превышает свой timeout, Claude Code отменяет его и отбрасывает его выходные данные, и сеанс продолжается, а не зависает. Что происходит дальше, зависит от события:Когда callback превышает свой таймаут, Claude Code отменяет его и отбрасывает его выходные данные, и сессия продолжается, а не зависает. Что происходит дальше, зависит от события:
834 834
835835* `PreToolUse`: Claude Code не запускает вызов инструмента, Claude получает результат инструмента, указывающий, что hook не ответил до истечения timeout, и ход продолжается. Если другой hook `PreToolUse` вернул явный отказ, Claude получает этот отказ вместо ошибки timeout. До версии 2.1.210 Claude Code сообщал timeout Claude как отклонение пользователем, что заставляло автоматические сеансы остановиться и ждать ввода.* `PreToolUse`: Claude Code не выполняет вызов инструмента, Claude получает результат инструмента, указывающий, что хук не ответил до истечения таймаута, и ход продолжается. Если другой хук `PreToolUse` вернул явный отказ, Claude получает этот отказ вместо ошибки таймаута. До версии 2.1.210 Claude Code сообщал Claude о таймауте как об отклонении пользователем, из-за чего автоматические сессии останавливались и ждали ввода.
836836* `PostToolUse` и `PostToolUseFailure`: Claude Code сохраняет результат инструмента и ход продолжается.* `PostToolUse` и `PostToolUseFailure`: Claude Code сохраняет результат инструмента, и ход продолжается.
837837* `UserPromptSubmit` и [`UserPromptExpansion`](/docs/ru/hooks#userpromptexpansion): Claude Code блокирует запрос с сообщением, указывающим hook и timeout, и сеанс продолжается. Поскольку callback на этих событиях может действовать как политический шлюз, Claude Code никогда не пропускает истекший по времени запрос без проверки. До версии 2.1.208 Claude Code завершал запрос с `error_during_execution`, когда callback на этих событиях истекал по времени.* `UserPromptSubmit` и [`UserPromptExpansion`](/docs/ru/hooks#userpromptexpansion): Claude Code блокирует промпт с сообщением, указывающим хук и таймаут, и сессия продолжается. Поскольку callback на этих событиях может действовать как шлюз политики, Claude Code никогда не пропускает промпт с истекшим таймаутом без проверки. До версии 2.1.208 Claude Code завершал запрос с `error_during_execution`, когда у callback на этих событиях истекал таймаут.
838838* `Stop` и `SubagentStop`: истекший по времени callback считается возвращающим отсутствие решения. Агент или подагент останавливается так, как если бы этот callback разрешил это, и решение из ваших других hooks на событие все еще применяется. До Claude Code версии 2.1.273 истекший по времени callback `Stop` или `SubagentStop` считался неудачным запуском hook, и Claude Code отбрасывал решения ваших других hooks на событие.* `Stop` и `SubagentStop`: callback с истекшим таймаутом считается не вернувшим решения. Агент или субагент останавливается так, как если бы этот callback это разрешил, а решение ваших других хуков на этом событии по-прежнему применяется. До Claude Code версии 2.1.273 callback `Stop` или `SubagentStop` с истекшим таймаутом считался неудачным запуском хука, и Claude Code отбрасывал решения ваших других хуков на этом событии.
839839* `SessionStart`: истекший по времени callback считается возвращающим отсутствие выходных данных, и сеанс продолжается с выходными данными ваших других hooks `SessionStart`.* `SessionStart`: callback с истекшим таймаутом считается не вернувшим выходных данных, и сессия продолжается с выходными данными ваших других хуков `SessionStart`.
840840* `PreModelSwitch`: Claude Code блокирует переключение модели. Hook, который не отвечает, не одобрил переключение.* `PreModelSwitch`: Claude Code блокирует переключение модели. Хук, который не отвечает, не одобрил переключение.
841841* Другие события, такие как `Notification`, `PreCompact` и `PostModelSwitch`: Claude Code логирует сбой и продолжает.* Другие события, такие как `Notification`, `PreCompact` и `PostModelSwitch`: Claude Code записывает сбой в лог и продолжает работу.
842 842
843843Первый раз, когда callback `Stop` или `SessionStart` истекает по времени в основном сеансе, Claude Code также добавляет [`SDKInformationalMessage`](/docs/ru/agent-sdk/typescript#sdkinformationalmessage) в поток сообщений, говоря, что приложение, управляющее сеансом, не ответило. Более поздние timeout не повторяют это сообщение, пока ваше приложение остается неответчивым.Когда у callback `Stop` или `SessionStart` впервые истекает таймаут в основной сессии, Claude Code также добавляет в поток сообщений [`SDKInformationalMessage`](/docs/ru/agent-sdk/typescript#sdkinformationalmessage) о том, что приложение, управляющее сессией, не ответило. Последующие таймауты не повторяют это сообщение, пока ваше приложение остается неотвечающим.
844 844
845845Если вы прерываете запрос во время ожидания callback, Claude Code отменяет ожидающий вызов инструмента. До версии 2.1.208 вызов инструмента мог все еще продолжиться, если вы прервали во время ожидания callback `PreToolUse`.Если вы прерываете запрос во время ожидания callback, Claude Code отменяет ожидающий вызов инструмента. До версии 2.1.208 вызов инструмента мог все же выполниться, если вы прерывали запрос во время ожидания callback `PreToolUse`.
846 846
847847Если вашему callback нужно больше времени, установите более высокий `timeout` на его `HookMatcher`. В TypeScript используйте `AbortSignal` из третьего аргумента callback для корректной обработки отмены, когда истекает timeout.Если вашему callback нужно больше времени, установите более высокий `timeout` в его `HookMatcher`. В TypeScript используйте `AbortSignal` из третьего аргумента callback для корректной обработки отмены при срабатывании таймаута.
848 848
849<h3 id="tool-blocked-unexpectedly">849<h3 id="tool-blocked-unexpectedly">
850 Инструмент заблокирован неожиданно850 Инструмент заблокирован неожиданно
851</h3>851</h3>
852 852
853853* Проверьте все hooks `PreToolUse` на возвращение `permissionDecision: 'deny'`* Проверьте все хуки `PreToolUse` на возвращение `permissionDecision: 'deny'`
854854* Добавьте логирование в ваши hooks, чтобы увидеть, какие `permissionDecisionReason` они возвращают* Добавьте логирование в ваши хуки, чтобы увидеть, какие `permissionDecisionReason` они возвращают
855* Проверьте, что паттерны matcher не слишком широкие: пустой matcher соответствует всем инструментам855* Проверьте, что паттерны matcher не слишком широкие: пустой matcher соответствует всем инструментам
856 856
857<h3 id="modified-input-not-applied">857<h3 id="modified-input-not-applied">
858858 Измененный входной сигнал не применяется Измененные входные данные не применяются
859</h3>859</h3>
860 860
861* Убедитесь, что `updatedInput` находится внутри `hookSpecificOutput`, а не на верхнем уровне:861* Убедитесь, что `updatedInput` находится внутри `hookSpecificOutput`, а не на верхнем уровне:
870 };870 };
871 ```871 ```
872 872
873873* Не объединяйте `updatedInput` с `permissionDecision: 'defer'`, который отбрасывает измененный входной сигнал. Опущение `permissionDecision` допустимо: измененный входной сигнал все еще применяется через обычную оценку разрешений. Вы также можете вернуть `'allow'` для автоматического одобрения измененного входного сигнала или `'ask'` для отображения его пользователю на утверждение* Не объединяйте `updatedInput` с `permissionDecision: 'defer'`, так как это отбрасывает измененные входные данные. Опускать `permissionDecision` допустимо: измененные входные данные все равно применяются через обычную оценку разрешений. Вы также можете вернуть `'allow'` для автоматического одобрения измененных входных данных или `'ask'`, чтобы показать их пользователю для подтверждения
874 874
875875* Включите `hookEventName` в `hookSpecificOutput` для идентификации типа hook, для которого предназначен вывод* Включите `hookEventName` в `hookSpecificOutput`, чтобы указать, к какому типу хука относится вывод
876 876
877<h3 id="session-hooks-not-available-in-python">877<h3 id="session-hooks-not-available-in-python">
878878 Hooks сеанса недоступны в Python Хуки сессии недоступны в Python
879</h3>879</h3>
880 880
881881`SessionStart` и `SessionEnd` могут быть зарегистрированы как SDK callback hooks в TypeScript, но недоступны в Python SDK, потому что его тип `HookEvent` их опускает. В Python они доступны только как [shell command hooks](/docs/ru/hooks#hook-events), определенные в файлах настроек, таких как `.claude/settings.json`. Для загрузки shell command hooks из вашего приложения SDK включите соответствующий источник настроек с [`setting_sources`](/docs/ru/agent-sdk/python#settingsource) или [`settingSources`](/docs/ru/agent-sdk/typescript#settingsource):`SessionStart` и `SessionEnd` можно зарегистрировать как callback-хуки SDK в TypeScript, но они недоступны в Python SDK, потому что его тип `HookEvent` их не включает. В Python они доступны только как [хуки shell-команд](/docs/ru/hooks#hook-events), определенные в файлах настроек, таких как `.claude/settings.json`. То, какие файлы настроек загружает ваше приложение SDK, зависит от [`setting_sources`](/docs/ru/agent-sdk/python#settingsource) или [`settingSources`](/docs/ru/agent-sdk/typescript#settingsource). Если вы задаете этот параметр, включите источник, который содержит хуки:
882 882
883<CodeGroup>883<CodeGroup>
884 ```python Python theme={null}884 ```python Python theme={null}
894 ```894 ```
895</CodeGroup>895</CodeGroup>
896 896
897897Для запуска логики инициализации как Python SDK callback вместо этого используйте первое сообщение из `client.receive_response()` как ваш триггер.Чтобы вместо этого запускать логику инициализации как callback Python SDK, используйте первое сообщение из `client.receive_response()` в качестве триггера.
898 898
899<h3 id="subagent-permission-prompts-multiplying">899<h3 id="subagent-permission-prompts-multiplying">
900900 Запросы разрешений подагента умножаются Запросы разрешений субагентов множатся
901</h3>901</h3>
902 902
903903При порождении нескольких подагентов каждый может запросить разрешения отдельно для своих собственных вызовов инструментов. Чтобы избежать повторных запросов, используйте hooks `PreToolUse` для автоматического одобрения конкретных инструментов или настройте правила разрешений, которые подагенты [наследуют от родительского разговора](/docs/ru/sub-agents#permission-modes).При порождении нескольких субагентов каждый из них может запрашивать разрешения отдельно для своих собственных вызовов инструментов. Чтобы избежать повторных запросов, используйте хуки `PreToolUse` для автоматического одобрения конкретных инструментов или настройте правила разрешений, которые субагенты [наследуют от родительского диалога](/docs/ru/sub-agents#permission-modes).
904 904
905<h3 id="recursive-hook-loops-with-subagents">905<h3 id="recursive-hook-loops-with-subagents">
906906 Рекурсивные циклы hook с подагентами Рекурсивные циклы хуков с субагентами
907</h3>907</h3>
908 908
909909Hook `UserPromptSubmit`, который порождает подагентов, может создать бесконечные циклы, если эти подагенты срабатывают тот же hook. Чтобы предотвратить это:Хук `UserPromptSubmit`, который порождает субагентов, может создать бесконечные циклы, если эти субагенты вызывают срабатывание того же хука. Чтобы предотвратить это:
910 910
911911* Используйте общую переменную или состояние сеанса для отслеживания, находитесь ли вы уже внутри подагента* Используйте общую переменную или состояние сессии для отслеживания того, находитесь ли вы уже внутри субагента
912912* Ограничьте область действия hooks, чтобы они запускались только для сеанса агента верхнего уровня* Ограничьте хуки, чтобы они запускались только для сессии агента верхнего уровня
913 913
914<h3 id="systemmessage-not-appearing-in-output">914<h3 id="systemmessage-not-appearing-in-output">
915 systemMessage не появляется в выводе915 systemMessage не появляется в выводе
916</h3>916</h3>
917 917
918918Поле `systemMessage` показывает сообщение пользователю, а не модели. На Claude Code версии 2.1.227 или позже, `systemMessage` hook может появиться в потоке сообщений как [`SDKInformationalMessage`](/docs/ru/agent-sdk/typescript#sdkinformationalmessage). Появляется ли оно, зависит от события. Каждый [раздел события](/docs/ru/hooks#hook-events) на странице hooks говорит, как выводится результат. Для передачи контекста модели вместо этого верните [`additionalContext`](/docs/ru/hooks#add-context-for-claude).Поле `systemMessage` показывает сообщение пользователю, а не модели. В Claude Code версии 2.1.227 или новее `systemMessage` хука может появиться в потоке сообщений как [`SDKInformationalMessage`](/docs/ru/agent-sdk/typescript#sdkinformationalmessage). Появится ли оно, зависит от события. В [разделе каждого события](/docs/ru/hooks#hook-events) на странице хуков описано, как выводится результат. Чтобы вместо этого передать контекст модели, верните [`additionalContext`](/docs/ru/hooks#add-context-for-claude).
919 919
920920До версии 2.1.227 SDK выводил выходные данные hook в поток сообщений только для hooks `SessionStart` и `Setup`. Для любого другого события выходные данные появлялись только в событиях жизненного цикла, которые добавляет [`includeHookEvents`](/docs/ru/agent-sdk/typescript#options) (`include_hook_events` в Python). Запись этого параметра охватывает, какие события жизненного цикла производит каждое событие hook.До версии 2.1.227 SDK выводил выходные данные хука в поток сообщений только для хуков `SessionStart` и `Setup`. Для любого другого события выходные данные появлялись только в событиях жизненного цикла, которые добавляет [`includeHookEvents`](/docs/ru/agent-sdk/typescript#options) (`include_hook_events` в Python). В описании этого параметра указано, какие события жизненного цикла порождает каждое событие хука.
921 921
922922Если вам нужно надежно вывести решения hook в ваше приложение, логируйте их отдельно или используйте выделенный канал вывода.Если вам нужно надежно передавать решения хуков в ваше приложение, логируйте их отдельно или используйте выделенный канал вывода.
923 923
924<h2 id="related-resources">924<h2 id="related-resources">
925 Связанные ресурсы925 Связанные ресурсы