AIKraft Agents
Главная/Документация/Справочник агента/Настройка автоматизаций
Справочник агента

Настройка автоматизаций

Руководство по настройке автоматизаций в AIKraft Agents для запуска действий по событиям, расписанию и условиям.

Это руководство объясняет, как настроить автоматизации в AIKraft Agents для автоматизации рабочих процессов на основе событий.

Рекомендуемый подход через CLI: используйте команды craft-agent automation ... вместо прямого редактирования JSON.

  • craft-agent automation --help
  • Канонический справочник команд: craft-cli.md

Что такое автоматизации?

Автоматизации позволяют автоматически запускать действия при наступлении определенных событий в AIKraft Agents. Вы можете:

  • Отправлять запросы для создания сессий агента на основе событий
  • Отправлять HTTP-запросы webhook во внешние сервисы (Slack, Discord, собственные API и т. д.)
  • Выполнять действия по расписанию с использованием выражений cron
  • Автоматизировать рабочие процессы на основе изменений режима прав, флагов или статуса сессии

Расположение automations.json

Автоматизации настраиваются в файле automations.json в корне вашего workspace:

terminalbash
~/.craft-agent/workspaces/{workspaceId}/automations.json

Рекомендуемые команды CLI

terminalbash
craft-agent automation list
craft-agent automation get <id>
craft-agent automation create --event UserPromptSubmit --prompt "..."
craft-agent automation update <id> --json '{...}'
craft-agent automation enable <id>
craft-agent automation disable <id>
craft-agent automation duplicate <id>
craft-agent automation history [<id>] --limit 20
craft-agent automation last-executed <id>
craft-agent automation test <id> --match "..."
craft-agent automation lint
craft-agent automation validate

Базовая структура

terminaljson
{
  "version": 2,
  "automations": {
    "EventName": [
      {
        "name": "Необязательное отображаемое имя",
        "matcher": "regex-pattern",
        "actions": [
          { "type": "prompt", "prompt": "Проверьте обновления и сообщите статус" }
        ]
      }
    ]
  }
}

Поддерживаемые события

События приложения (генерируются AIKraft Agents)

СобытиеТриггерЗначение для сопоставления
LabelAddЛейбл добавлен к сессииID лейбла (например, bug, а не Bug)
LabelRemoveЛейбл удален из сессииID лейбла (например, bug, а не Bug)
LabelConfigChangeИзменена конфигурация лейблаВсегда совпадает
PermissionModeChangeИзменен режим правНовое название режима
FlagChangeСессия помечена/разомечена флагомtrue или false
SessionStatusChangeИзменен статус сессииНовый статус (например, done, in_progress)
SchedulerTickВыполняется каждую минутуИспользуется сопоставление cron

Примечание: TodoStateChange — это устаревший псевдоним для SessionStatusChange. Существующие конфигурации, использующие старое имя, продолжат работать, но при валидации будет выдано предупреждение об устаревании.

События агента

Сопоставители событий агента с действием prompt создают отдельную сессию автоматизации. Переопределения llmConnection и model в действии применяются точно так же, как для запросов по расписанию или событий приложения. Диспетчеризация не блокирующая, поэтому автоматизация PreToolUse не ждет завершения дочерней сессии.

Сессии, созданные автоматизацией, не запускают автоматизации событий агента повторно. Это предотвращает рекурсивные цепочки SessionStart / UserPromptSubmit. В этой версии действия, отличные от prompt, для событий агента игнорируются.

СобытиеТриггерЗначение для сопоставления
PreToolUseПеред выполнением инструментаИмя инструмента
PostToolUseПосле успешного выполнения инструментаИмя инструмента
PostToolUseFailureПосле неудачного выполнения инструментаИмя инструмента
NotificationПолучено уведомление-
UserPromptSubmitПользователь отправил запрос-
SessionStartСессия началась-
SessionEndСессия завершилась-
StopАгент остановился-
SubagentStartСоздан субагент-
SubagentStopСубагент завершил работу-
PreCompactПеред сжатием контекста-
PermissionRequestЗапрошены права-
SetupНачальная настройка-

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

Действия Prompt

Отправляют запрос в AIKraft Agents. Запросы по расписанию, события приложения и события агента создают новую сессию автоматизации.

terminaljson
{
  "type": "prompt",
  "prompt": "Запустите скилл @weather и обобщите прогноз"
}
СвойствоТипПо умолчаниюОписание
type"prompt"ОбязательноТип действия
promptstringОбязательноТекст запроса для отправки
llmConnectionstringПо умолчанию workspaceSlug LLM-подключения (настроено в настройках ИИ)
modelstringПо умолчанию workspaceID модели для созданной сессии

Возможности:

  • Используйте @mentions для ссылок на источники или скиллы
  • Переменные окружения раскрываются (например, $CRAFT_LABEL)

LLM-подключение и модель: Необязательно указать, какой провайдер ИИ и модель будут использоваться для созданной сессии. Если не указано, используются значения по умолчанию workspace.

terminaljson
{
  "type": "prompt",
  "prompt": "Быстрый код-ревью последних изменений",
  "llmConnection": "my-copilot-connection",
  "model": "gemini-2.5-flash"
}

Значение llmConnection — это slug LLM-подключения, настроенного в настройках ИИ. Значение model — это ID модели, поддерживаемый провайдером. Если одно из них недействительно или не найдено, система корректно переключается на значения по умолчанию workspace. Оба поля можно использовать независимо или вместе.

Действия Webhook

Отправляют HTTP-запрос во внешний endpoint при срабатывании события. Полезно для уведомлений (Slack, Discord), логирования во внешние сервисы или запуска внешних рабочих процессов.

terminaljson
{
  "type": "webhook",
  "url": "https://hooks.slack.com/services/${CRAFT_WH_SLACK_PATH}",
  "method": "POST",
  "body": {
    "text": "Статус сессии ${CRAFT_SESSION_NAME} изменен на ${CRAFT_NEW_STATE}"
  }
}
СвойствоТипПо умолчаниюОписание
type"webhook"ОбязательноТип действия
urlstringОбязательноЦелевой URL (http или https)
method"GET" | "POST" | "PUT" | "PATCH" | "DELETE""POST"Метод HTTP
headersRecord<string, string>{}Заголовки HTTP в виде пар ключ-значение
bodyFormat"json" | "form" | "raw""json"Формат сериализации тела запроса
bodyobject или string-Тело запроса (опускается для GET-запросов)
authobject-Краткая запись аутентификации (см. ниже)
captureResponsebooleanfalseСохранить тело ответа в результате (обрезается до 4 КБ)

Валидация URL: Литеральные URL проверяются при загрузке конфигурации. URL с шаблонами (содержащие $VAR) проверяются во время выполнения после раскрытия переменных. Оба должны разрешаться в http:// или https:// — другие протоколы отклоняются.

Формат тела:

  • json (по умолчанию) — Тело сериализуется как JSON. Заголовок Content-Type: application/json устанавливается автоматически, если вы не переопределили его в headers.
  • form — Ключи объекта тела кодируются в URL как application/x-www-form-urlencoded. Полезно для endpoint'ов токенов OAuth, Stripe и устаревших API. Каждое значение поддерживает раскрытие $VAR.
  • raw — Тело отправляется как обычная строка. Установите Content-Type в headers самостоятельно.

Аутентификация:

Вместо ручной сборки заголовка Authorization можно использовать краткую запись auth:

Bearer-токен:

terminaljson
{
  "type": "webhook",
  "url": "https://api.example.com/events",
  "auth": {
    "type": "bearer",
    "token": "${CRAFT_WH_API_TOKEN}"
  },
  "body": { "event": "$CRAFT_EVENT" }
}

Базовая аутентификация (имя пользователя/пароль):

terminaljson
{
  "type": "webhook",
  "url": "https://legacy.example.com/webhook",
  "auth": {
    "type": "basic",
    "username": "${CRAFT_WH_USER}",
    "password": "${CRAFT_WH_PASS}"
  }
}

Поле auth применяется до пользовательских headers, поэтому при необходимости вы можете переопределить сгенерированный заголовок Authorization. Все значения полей аутентификации поддерживают раскрытие $VAR.

Сохранение ответа: По умолчанию тела ответов webhook отбрасываются после чтения (для освобождения соединений). Установите captureResponse: true, чтобы сохранить тело ответа (обрезается до 4 КБ). Сохраненное тело включается в результат выполнения и записывается в историю автоматизации (обрезается до 500 символов).

terminaljson
{
  "type": "webhook",
  "url": "https://api.example.com/status",
  "method": "GET",
  "captureResponse": true
}

Примечание: Сохранение ответа добавляет накладные расходы на память, пропорциональные размеру ответа. Включайте его только для endpoint'ов, где необходимо проверить ответ.

Раскрытие переменных: Поля url, значения headers, body и auth поддерживают синтаксис $VAR и ${VAR} для раскрытия переменных окружения. См. Переменные окружения ниже.

Безопасность: Действия webhook имеют доступ только к системным переменным CRAFT_* и пользовательским секретам CRAFT_WH_*. У них нет доступа к полному окружению системы (например, $HOME, $PATH или другим переменным процесса).

Переменные окружения

Действия prompt и webhook поддерживают раскрытие переменных с использованием синтаксиса $VAR или ${VAR}.

Системные переменные (CRAFT_*)

Они автоматически устанавливаются системой автоматизаций на основе события-триггера:

ПеременнаяОписаниеДоступна для
$CRAFT_EVENTИмя события (например, LabelAdd)Все события
$CRAFT_EVENT_DATAПолный payload события в формате JSONВсе события
$CRAFT_SESSION_IDID сессииСобытия с контекстом сессии
$CRAFT_SESSION_NAMEИмя сессииСобытия с контекстом сессии
$CRAFT_WORKSPACE_IDID workspaceВсе события

Переменные для конкретных событий:

СобытиеПеременнаяОписание
LabelAdd / LabelRemove$CRAFT_LABELЛейбл, который был добавлен/удален
PermissionModeChange$CRAFT_OLD_MODE, $CRAFT_NEW_MODEПредыдущий и новый режим прав
FlagChange$CRAFT_IS_FLAGGEDtrue или false
SessionStatusChange$CRAFT_OLD_STATE, $CRAFT_NEW_STATEПредыдущий и новый статус
SchedulerTick$CRAFT_LOCAL_TIME, $CRAFT_LOCAL_DATEТекущее время (14:30) и дата (2026-03-09)

Пользовательские секреты Webhook (CRAFT_WH_*)

Для действий webhook вы можете определить собственные секреты, установив переменные окружения с префиксом CRAFT_WH_ в профиле вашей оболочки (например, ~/.zshrc, ~/.bashrc):

terminalbash
# В профиле вашей оболочки
export CRAFT_WH_SLACK_URL="https://hooks.slack.com/services/T.../B.../xxx"
export CRAFT_WH_DISCORD_URL="https://discord.com/api/webhooks/123/abc"
export CRAFT_WH_API_TOKEN="your-secret-token"

Затем ссылайтесь на них в automations.json:

terminaljson
{
  "type": "webhook",
  "url": "${CRAFT_WH_SLACK_URL}",
  "method": "POST",
  "body": { "text": "Привет от AIKraft Agents!" }
}
terminaljson
{
  "type": "webhook",
  "url": "https://api.example.com/events",
  "headers": { "Authorization": "Bearer ${CRAFT_WH_API_TOKEN}" },
  "body": { "event": "${CRAFT_EVENT}", "session": "${CRAFT_SESSION_NAME}" }
}

Это позволяет не хранить секреты в automations.json (который может быть общим или добавленным в систему контроля версий).

Примечание: В действия webhook внедряются только переменные с префиксом CRAFT_WH_. Другие переменные окружения (например, $HOME или $DATABASE_URL) недоступны для webhook.

Примечание: Переменные окружения не раскрываются во время тестовых запусков (кнопка «Тест» в интерфейсе). Тесты отправляют «сырой» URL/тело, как настроено.

Настройка сопоставителя (Matcher)

Отображаемое имя

Используйте необязательное поле name, чтобы дать автоматизации человекочитаемое отображаемое имя. Если опущено, имя автоматически выводится из первого действия.

terminaljson
{
  "name": "Утренний отчет о погоде",
  "cron": "0 8 * * *",
  "actions": [
    { "type": "prompt", "prompt": "Запустите скилл @weather" }
  ]
}

Сопоставление по регулярному выражению (для большинства событий)

Используйте поле matcher, чтобы отфильтровать, какие события запускают ваши автоматизации:

terminaljson
{
  "matcher": "^urgent$",
  "actions": [
    { "type": "prompt", "prompt": "Добавлен срочный лейбл. Просмотрите сессию и обобщите проблему." }
  ]
}

Если matcher опущено, автоматизация срабатывает для всех событий этого типа.

Сопоставление по Cron (для SchedulerTick)

Для событий SchedulerTick используйте выражения cron вместо регулярных выражений:

terminaljson
{
  "cron": "0 9 * * 1-5",
  "timezone": "America/New_York",
  "actions": [
    { "type": "prompt", "prompt": "Дай мне утренний брифинг" }
  ]
}

Формат Cron: минута час день-месяца месяц день-недели

ПолеЗначения
Минута0-59
Час0-23
День месяца1-31
Месяц1-12
День недели0-6 (0 = воскресенье)

Примеры:

  • */15 * * * * — Каждые 15 минут
  • 0 9 * * * — Ежедневно в 9:00 утра
  • 0 9 * * 1-5 — В будни в 9:00 утра
  • 30 14 1 * * — 1-го числа каждого месяца в 14:30

Часовой пояс: Используйте имена часовых поясов IANA (например, Europe/Budapest, America/New_York). Если не указано, используется системный часовой пояс.

Разовый запуск (runAt)

Разовая автоматизация — это матчер SchedulerTick с runAt вместо cron. Срабатывает один раз и больше никогда.

terminaljson
{
  "name": "Проверить оплату от ООО Ромашка",
  "runAt": "2026-10-05T10:00:00+03:00",
  "timezone": "Europe/Moscow",
  "permissionMode": "safe",
  "origin": { "sessionId": "260928-bold-oak", "createdBy": "agent" },
  "actions": [
    { "type": "prompt", "prompt": "Проверь, пришла ли оплата от ООО Ромашка, и напиши итог" }
  ]
}
ПолеКто пишетСмысл
runAtчеловек / агентМомент запуска: ISO-8601 с зоной (+03:00 или Z). Без зоны — ошибка валидации.
graceMinutesчеловек / агентОкно догона, минут (по умолчанию 720, максимум 43200).
originагентОткуда взялась: sessionId, createdBy.
firedAtпланировщикКогда сработала. Пишется на диск до исполнения действий.
missedAtпланировщикОпоздали больше окна — не исполнялась.
runSessionIdпланировщикСессия, которую создало prompt-действие.
calendarEventIdсинк календаряСобытие в календаре «Запуски» места.

Правила:

  • cron и runAt взаимоисключающие; runAt допустим только у SchedulerTick. Иначе — ошибка валидации: запись файла (агент, интерфейс, upsert) такую разовую не примет. Если брак всё же попал в файл руками, сервер при загрузке пропускает только эту разовую (в журнале — событие, номер и id), остальные автоматизации работают. После ручной правки — config_validate с target: "automations" (команды craft-agent automation … нет).
  • Сервер, импорт ресурсов и синк календаря пишут automations.json под общим замком — flock на файле .automations.json.lock рядом с ним — на всё время «прочитать → поправить → записать». Файл замка не удалять: пока держатель жив, замок его; умер — замок снимает система. Не загрузился замок у сервера (Bun без flock из libc) — сервер automations.json не пишет вовсе: разовые не срабатывают, правки и импорт отклоняются с ошибкой «automations.json interprocess lock is unavailable under Bun», в журнале сервера одна строка об этом. Писать файл в обход в этот момент нельзя — чинится сервер.
  • Правка агента инструментом Edit/Write идёт мимо замка: если в тот же миг сервер записал firedAt, запись агента его сотрёт, и разовая сработает второй раз. Поэтому существующую разовую (перенести, повторить, отменить, сделать постоянной) правят кнопками «Автоматизации → Разовые» — они идут через замок. Edit — для новой записи и когда человека нет в интерфейсе: перечитать файл прямо перед правкой и не править его в минуту срабатывания активной разовой.
  • Срабатывает на первом тике, где сейчас >= runAt: пропущенная минута и рестарт сервера догоняются.
  • Опоздание больше graceMinutes — действие не исполняется, ставится missedAt.
  • firedAt/missedAt/runSessionId вручную не писать и не копировать в новую разовую.
  • conditions, permissionMode, labels, агент (agentSlug), модель, источники и навыки действия работают так же, как у постоянной.

Состояния (так их показывает раздел «Разовые» в интерфейсе):

СостояниеПризнак
ждет запускаenabled !== false, нет firedAt и missedAt
выполненаесть firedAt (ссылка на runSessionId)
пропущенаесть missedAt
отмененаenabled: false, нет firedAt

Правки (кнопки карточки, RPC automations:oneShotEdit):

  • Перенести — новая runAt, снимаются firedAt/missedAt/runSessionId, запись включается; calendarEventId остается.
  • Повторить — копия с новым id и новой runAt, без служебных полей и без calendarEventId.
  • Сделать постоянной — runAt → cron, все поля разовой снимаются.
  • Отменить — enabled: false.

Условия (Conditions)

Условия — это необязательные фильтры, которые выполняются после совпадения матчера/cron, но до запуска действий. Все условия в массиве должны пройти (неявное И). Если массив пуст или опущен, действия запускаются без условий.

terminaljson
{
  "cron": "0 9 * * *",
  "timezone": "Europe/Budapest",
  "conditions": [
    {
      "condition": "time",
      "weekday": ["mon", "tue", "wed", "thu", "fri"]
    }
  ],
  "actions": [
    { "type": "prompt", "prompt": "Доброе утро! Вот ваш ежедневный брифинг." }
  ]
}

Временные условия

Проверяют время суток и день недели в указанном часовом поясе.

terminaljson
{
  "condition": "time",
  "after": "09:00",
  "before": "17:00",
  "weekday": ["mon", "tue", "wed", "thu", "fri"],
  "timezone": "Europe/Budapest"
}
СвойствоТипОписание
after"HH:MM"Начало временного окна (включительно)
before"HH:MM"Конец временного окна (не включительно)
weekdaystring[]Разрешенные дни: mon, tue, wed, thu, fri, sat, sun
timezonestringЧасовой пояс IANA. Если не указан, используется часовой пояс матчера, затем локальный системный

Ночные диапазоны: Если after позже before (например, "after": "22:00", "before": "06:00"), диапазон перекрывается через полночь.

Состояние условий

Проверяют поля из payload события. Полезно для фильтрации по конкретным переходам или значениям.

terminaljson
{
  "condition": "state",
  "field": "permissionMode",
  "from": "safe",
  "to": "allow-all"
}
СвойствоТипОписание
fieldstringИмя поля payload (например, permissionMode, sessionStatus, labels, isFlagged)
valueanyТочное совпадение
fromanyПредыдущее значение (для событий перехода)
toanyНовое значение (для событий перехода)
containsstringПроверка членства в массиве (например, проверка наличия лейбла)
not_valueanyСовпадает со всем, кроме этого значения

Поля перехода: Для permissionMode и sessionStatus from/to автоматически разрешаются в правильные ключи payload (oldMode/newMode, oldState/newState).

Логическая композиция

Комбинируйте условия с помощью and, or и not:

terminaljson
{
  "condition": "and",
  "conditions": [
    { "condition": "time", "weekday": ["mon", "tue", "wed", "thu", "fri"] },
    { "condition": "time", "after": "09:00", "before": "17:00" }
  ]
}
terminaljson
{
  "condition": "or",
  "conditions": [
    { "condition": "state", "field": "permissionMode", "value": "allow-all" },
    { "condition": "state", "field": "isFlagged", "value": true }
  ]
}
terminaljson
{
  "condition": "not",
  "conditions": [
    { "condition": "time", "weekday": ["sat", "sun"] }
  ]
}
ТипПоведение
andВсе подусловия должны пройти
orХотя бы одно подусловие должно пройти
notНи одно из подусловий не должно пройти

Глубина вложенности: Условия могут быть вложены до 8 уровней. Предупреждение о упрощении выводится на глубине 4. Неизвестные типы условий срабатывают «на закрытие» (оцениваются как false).

Семантическое условие (требует Decision Model)

conditions могут только сравнивать поля. semanticCondition задает вопрос «да/нет», на который отвечает модель принятия решений (Jev, Настройки > ИИ > Модель принятия решений, переключатель «Условия автоматизации») перед тем, как prompt-действие запускает сессию:

terminaljson
{
  "matcher": "^needs-triage$",
  "semanticCondition": {
    "question": "Is the user reporting a bug or crash, rather than asking a question?",
    "threshold": 0.6
  },
  "actions": [{ "type": "prompt", "prompt": "Triage the bug in session $CRAFT_SESSION_NAME" }]
}
СвойствоТипОписание
questionstringОбязательно. Вопрос «да/нет», на английском (макс. 500 символов).
thresholdnumberВероятность «Да», необходимая для запуска, 0 < threshold <= 1. По умолчанию 0.5.
  • Модель видит событие (имя, имя автоматизации, поля payload) и, для событий сессии, имя сессии, лейблы, статус и ее последние сообщения пользователя и ассистента (по 1500 символов каждое).
  • Если порог не достигнут, запуск пропускается, и в истории автоматизации это записывается как пропуск, а не ошибка.
  • Матчер оценивается один раз на событие: либо выполняются все его prompt-действия, либо все пропускаются.
  • Неактивно без модели принятия решений: когда она выключена, недоступна или дает сбой, автоматизация работает так, как если бы условие отсутствовало.
  • Защита от циклов: автоматизация никогда не запускается для события, касающегося сессии, которую она сама создала (иначе ее собственный prompt, совпадающий с правилом лейбла, вызвал бы ее снова бесконечно), и цепочка сессий, созданных автоматизацией и запускающих другие автоматизации, останавливается на глубине 3 сессий. Такие запуски записываются как пропущенные.
  • Применяется только к prompt-действиям; webhook и script-действия не ограничиваются.

Режим прав (Permission Mode)

Поле permissionMode управляет уровнем прав сессий, создаваемых prompt-действиями.

terminaljson
{
  "cron": "*/10 * * * *",
  "permissionMode": "allow-all",
  "actions": [
    { "type": "prompt", "prompt": "Проверьте состояние системы и запишите результаты в лог" }
  ]
}

Режимы прав:

  • safe — Сессия работает в режиме Изучение (по умолчанию)
  • ask — Сессия запрашивает одобрение перед операциями записи
  • allow-all — Сессия автоматически одобряет все операции

Лейблы для Prompt-действий

Prompt-действия могут указывать лейблы, которые будут применены к создаваемой сессии:

terminaljson
{
  "cron": "0 9 * * *",
  "labels": ["Scheduled", "morning-briefing"],
  "actions": [
    { "type": "prompt", "prompt": "Дай мне приоритеты на сегодня" }
  ]
}

Это создает сессию с автоматически примененными лейблами «Scheduled» и «morning-briefing».

Маршрутизация тем Telegram

Когда супергруппа Telegram связана в Настройки → Сообщения → Telegram, установите telegramTopic в матчере, чтобы маршрутизировать созданные им сессии в отдельную тему форума. Тема создается при первом использовании и переиспользуется далее.

terminaljson
{
  "matcher": "^urgent$",
  "telegramTopic": "Urgent Alerts",
  "actions": [
    { "type": "prompt", "prompt": "Посмотри на срочную проблему: $LABEL" }
  ]
}
ПолеТипОписание
telegramTopicstring (1–128 символов)Имя темы. Создается при первом использовании, переиспользуется далее. Несколько матчеров, использующих одно и то же значение, делят одну тему.

Требования для активации (все должны выполняться; иначе поле молча игнорируется):

  • Супергруппа Telegram связана в Настройки → Сообщения → Telegram
  • Бот Telegram подключен
  • У бота есть административное право Manage Topics

Имена чувствительны к регистру: "Reports" и "reports" создают разные темы.

Настройка супергруппы Telegram

Если вы еще не связали супергруппу:

  1. Создайте / преобразуйте супергруппу с включенными темами. В Telegram откройте группу → нажмите на название группы → Редактировать (иконка карандаша) → включите Topics → Сохранить. Группа должна быть форум-супергруппой; обычные группы не могут хостить темы.
  2. Добавьте бота в супергруппу. Название группы → Добавить участников → найдите имя пользователя вашего бота → добавьте.
  3. Назначьте бота админом с правом «Manage Topics». Название группы → Редактировать → Администраторы → Добавить администратора → выберите бота → включите Manage Topics → Сохранить. Это шаг, который чаще всего пропускают; без него создание темы завершится ошибкой 400: not enough rights to create a topic.
  4. Свяжите супергруппу. В AIKraft Agents: Настройки → Сообщения → Telegram → Pair Supergroup. Скопируйте 6-значный код, затем в любой теме супергруппы введите /pair <code>. Бот подтвердит, и строка в настройках обновится с названием группы.

Проверьте, что в настройках в строке супергруппы отображается название группы. Если позже запуски автоматизации завершатся ошибкой, в ~/.craft-agent/logs/messaging-gateway.log будет показано automation_topic_bind_failed с основной ошибкой Telegram.

Полные примеры

Ежедневный отчет о погоде

terminaljson
{
  "version": 2,
  "automations": {
    "SchedulerTick": [
      {
        "name": "Daily Weather Report",
        "cron": "0 8 * * *",
        "timezone": "Europe/Budapest",
        "labels": ["Scheduled", "weather"],
        "actions": [
          { "type": "prompt", "prompt": "Run the @weather skill and give me today's forecast" }
        ]
      }
    ]
  }
}

ИИ-новости только в будни (с условиями)

Используйте условие time, чтобы ограничить ежедневное расписание только буднями:

terminaljson
{
  "version": 2,
  "automations": {
    "SchedulerTick": [
      {
        "name": "Morning AI news",
        "cron": "0 9 * * *",
        "timezone": "Europe/Budapest",
        "conditions": [
          {
            "condition": "time",
            "weekday": ["mon", "tue", "wed", "thu", "fri"],
            "timezone": "Europe/Budapest"
          }
        ],
        "labels": ["Scheduled", "ai-news"],
        "actions": [
          { "type": "prompt", "prompt": "Run the @ai-news skill and summarize today's AI developments" }
        ]
      }
    ]
  }
}

Ограничение режима прав (с условиями)

Уведомлять только тогда, когда режим прав меняется именно с safe на allow-all:

terminaljson
{
  "version": 2,
  "automations": {
    "PermissionModeChange": [
      {
        "conditions": [
          {
            "condition": "state",
            "field": "permissionMode",
            "from": "safe",
            "to": "allow-all"
          }
        ],
        "actions": [
          {
            "type": "webhook",
            "url": "${CRAFT_WH_SLACK_URL}",
            "method": "POST",
            "body": { "text": ":warning: Permission escalated from safe to allow-all in *${CRAFT_SESSION_NAME}*" }
          }
        ]
      }
    ]
  }
}

Логирование изменений лейблов

terminaljson
{
  "version": 2,
  "automations": {
    "LabelAdd": [
      {
        "actions": [
          { "type": "prompt", "prompt": "The label $CRAFT_LABEL was added. Log this change with a timestamp." }
        ]
      }
    ],
    "LabelRemove": [
      {
        "actions": [
          { "type": "prompt", "prompt": "The label $CRAFT_LABEL was removed. Log this change with a timestamp." }
        ]
      }
    ]
  }
}

Уведомление о срочном лейбле

terminaljson
{
  "version": 2,
  "automations": {
    "LabelAdd": [
      {
        "matcher": "^urgent$",
        "actions": [
          { "type": "prompt", "prompt": "An urgent label was added to this session. Triage the session and summarise what needs immediate attention." }
        ]
      }
    ]
  }
}

Уведомление об изменении режима прав

terminaljson
{
  "version": 2,
  "automations": {
    "PermissionModeChange": [
      {
        "matcher": "allow-all",
        "actions": [
          { "type": "prompt", "prompt": "The permission mode was changed to allow-all. Log the change and note any security implications." }
        ]
      }
    ]
  }
}

Уведомление в Slack при изменении статуса

Отправляет сообщение в Slack, когда сессия помечена как выполненная. Требует CRAFT_WH_SLACK_URL в профиле вашей оболочки.

terminaljson
{
  "version": 2,
  "automations": {
    "SessionStatusChange": [
      {
        "name": "Notify Slack on Done",
        "matcher": "^done$",
        "actions": [
          {
            "type": "webhook",
            "url": "${CRAFT_WH_SLACK_URL}",
            "method": "POST",
            "body": {
              "text": ":white_check_mark: Session *${CRAFT_SESSION_NAME}* marked as done"
            }
          }
        ]
      }
    ]
  }
}

Смешанные действия (Prompt + Webhook)

Одна автоматизация может иметь как prompt-, так и webhook-действия. Они выполняются по порядку.

terminaljson
{
  "version": 2,
  "automations": {
    "LabelAdd": [
      {
        "name": "Urgent: Notify and Triage",
        "matcher": "^urgent$",
        "actions": [
          {
            "type": "webhook",
            "url": "${CRAFT_WH_SLACK_URL}",
            "method": "POST",
            "body": { "text": ":rotating_light: Urgent label added to *${CRAFT_SESSION_NAME}*" }
          },
          {
            "type": "prompt",
            "prompt": "An urgent label was added. Triage the session and summarise what needs immediate attention."
          }
        ]
      }
    ]
  }
}

Форм-кодированный запрос (OAuth / Stripe)

terminaljson
{
  "version": 2,
  "automations": {
    "SchedulerTick": [
      {
        "name": "Refresh API Token",
        "cron": "0 */6 * * *",
        "actions": [
          {
            "type": "webhook",
            "url": "https://auth.example.com/oauth/token",
            "method": "POST",
            "bodyFormat": "form",
            "body": {
              "grant_type": "client_credentials",
              "client_id": "${CRAFT_WH_CLIENT_ID}",
              "client_secret": "${CRAFT_WH_CLIENT_SECRET}"
            }
          }
        ]
      }
    ]
  }
}

Webhook с пользовательскими заголовками

terminaljson
{
  "version": 2,
  "automations": {
    "SessionStatusChange": [
      {
        "name": "Log to External API",
        "actions": [
          {
            "type": "webhook",
            "url": "https://api.example.com/craft-events",
            "method": "POST",
            "headers": {
              "Authorization": "Bearer ${CRAFT_WH_API_TOKEN}",
              "X-Source": "craft-agent"
            },
            "body": {
              "event": "${CRAFT_EVENT}",
              "session_id": "${CRAFT_SESSION_ID}",
              "old_status": "${CRAFT_OLD_STATE}",
              "new_status": "${CRAFT_NEW_STATE}"
            }
          }
        ]
      }
    ]
  }
}

Валидация

Автоматизации валидируются, когда:

  1. Workspace загружается
  2. Вы редактируете automations.json (через хук PreToolUse)
  3. Вы запускаете config_validate с target automations или all

Использование config_validate:

Попросите AIKraft Agents валидировать вашу конфигурацию автоматизаций:

terminalbash
Validate my automations configuration

Или используйте инструмент config_validate напрямую с target: "automations".

Частые ошибки валидации:

  • Неверный синтаксис JSON
  • Неизвестные имена событий
  • Пустой массив действий
  • Неверное выражение cron
  • Неверный часовой пояс
  • Неверный шаблон регулярного выражения
  • Потенциально небезопасные шаблоны регулярных выражений (вложенные квантификаторы)

Для ручной валидации:

terminalbash
# Проверить синтаксис automations.json
cat automations.json | jq .

Поведение при повторных попытках

Действия webhook имеют два уровня автоматических повторных попыток:

Немедленная повторная попытка (временные сбои)

Если webhook завершается ошибкой сервера (5xx), тайм-аутом или ошибкой соединения, он автоматически повторяется до 2 раз с экспоненциальным откатом (1с → 2с → 4с). Ошибки клиента (4xx) не повторяются — они указывают на проблему с конфигурацией.

Отложенная повторная попытка (продолжительные сбои)

Если все немедленные повторные попытки не удались, webhook добавляется в персистентную очередь повторных попыток. Очередь повторяет с увеличивающимися интервалами:

ПопыткаЗадержкаНакопительно
1-я отложенная5 минут5 мин
2-я отложенная30 минут35 мин
3-я отложенная1 час~1.5 часа

После того как последняя отложенная попытка не удалась, webhook помечается как постоянно упавший в истории. Отложенные повторные попытки переживают перезапуск приложения.

Примечание: Повторяются только временные сбои (5xx, тайм-ауты, ошибки соединения). Ошибки клиента (4xx) указывают на проблему с конфигурацией и должны быть исправлены в automations.json.

Повторные попытки и ограничение частоты: Повторяемые запросы webhook учитываются в ограничении частоты на endpoint (30/мин на origin). Если повторная попытка превысит лимит, она откладывается до следующего окна повторных попыток.

Ограничения частоты

Для защиты от неконтролируемых автоматизаций (например, автоматизация, которая косвенно запускает себя в цикле), шина событий применяет ограничения частоты по типу события:

СобытиеМакс. срабатываний / минута
SchedulerTick60 (1/сек)
Все остальные (LabelAdd, FlagChange, PreToolUse и т. д.)10

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

Пример: Если у вас есть задача LabelAdd, которая запускает prompt, добавляющий лейбл обратно в сессию, она сработает не более 10 раз, прежде чем попасть под ограничение частоты, — предотвращая бесконечное создание сессий.

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

Автоматизация не срабатывает

  1. Проверьте имя события — Оно должно быть точным (например, LabelAdd, а не labeladd)
  2. Проверьте матчер — Регулярное выражение должно совпадать со значением события
  3. Проверьте cron — Для SchedulerTick проверьте выражение cron с помощью онлайн-инструмента
  4. Проверьте логи — Ищите [automations] или [Scheduler] в логах

Prompt не создает сессию

  1. Проверьте, что prompt не пуст
  2. Убедитесь, что @mentions ссылаются на валидные источники/скиллы

Webhook не работает

  1. Проверьте URL — Должен быть валидным URL http:// или https://. Другие протоколы (ftp, ws и т. д.) отклоняются во время выполнения с явной ошибкой.
  2. Проверьте переменные окружения — Убедитесь, что переменные CRAFT_WH_* установлены в профиле вашей оболочки и AIKraft Agents был перезапущен после их добавления. URL, использующие шаблоны $VAR, валидируются после раскрытия переменных — если переменная пуста или не установлена, URL будет недействительным.
  3. Используйте кнопку Тест — Тестирует подключение к URL (примечание: переменные окружения не раскрываются во время теста)
  4. Проверьте метод — Некоторые endpoint'ы требуют конкретных методов HTTP (POST, PUT и т. д.)
  5. Проверьте ответ — История автоматизации показывает коды статуса HTTP для выполнений webhook

Повторные попытки для упавших webhook

Когда выполнение webhook завершается ошибкой (отображается с красным индикатором в таймлайне), вы можете повторить его:

  1. Откройте страницу деталей автоматизации
  2. В таймлайне «Недавняя активность» упавшие записи webhook показывают кнопку Retry
  3. Нажмите «Retry», чтобы немедленно повторно выполнить действия webhook
  4. Результат повторной попытки записывается как новая запись в истории

Примечание: Повторные попытки выполняют действия webhook в текущей конфигурации. Если вы изменили URL или заголовки после исходной ошибки, повторная попытка использует обновленную конфигурацию. Переменные окружения не раскрываются во время воспроизведения (как и для кнопки Тест).

Лучшие практики

  1. Начинайте с простого — Тестируйте с базовым prompt перед построением сложных рабочих процессов
  2. Используйте лейблы — Помечайте запланированные сессии для удобной фильтрации
  3. Будьте конкретны — Используйте матчеры, чтобы избежать срабатывания на каждое событие
  4. Тестируйте cron — Используйте crontab.guru для проверки выражений
  5. Держите секреты вне конфигурации — Используйте переменные окружения CRAFT_WH_* для URL и токенов webhook вместо их хардкода в automations.json
  6. Комбинируйте действия — Используйте как webhook-, так и prompt-действия в одной автоматизации для рабочих процессов «уведомление + ответ ИИ»

Нужен такой агент в вашей компании?

Устанавливаем под ключ: настройка на компьютерах сотрудников, единый аккаунт, интеграция с 1С и внутренними системами, обучение команды. Подробнее о внедрении →