Хранилище процесса — это JSON-объект, общий для одного запуска процесса. Через него задачи передают друг другу данные: идентификаторы, массивы для обхода в цикле, промежуточные результаты и сформированные тексты.

Запись выполняется только по правилам в конфигурации действий и элементов «Шаблон», а также элементом «AI-агент», который записывает результат агента по заданному ключу. Чтение — через Go-шаблоны {{ .store.<путь> }} в теле запроса, условиях шлюзов и других полях с поддержкой шаблонизации.

Модель данных

  • Одно хранилище на запуск — у каждого экземпляра процесса своё хранилище; оно сохраняется между шагами и доступно при просмотре запуска. Принудительный перезапуск процесса очищает хранилище.
  • Вложенные пути — ключи задаются dot-path без ведущей точки: notification.module_name, ctx.job.id. Промежуточные объекты создаются автоматически. Так же записывают значения элементы «Шаблон» и «AI-агент»: ключ notification.summary дополняет объект notification, а не создаёт ключ с точкой в имени.
  • Занятый путь — если путь проходит через значение, которое не является объектом, например ключ notification.module_name.short, когда в notification.module_name записана строка, элементы «Шаблон» и «AI-агент» завершаются с ошибкой write store key.
  • Индексы массивов — в пути можно указывать элемент массива: items[0].status, branches[2].name. Индекс — от 0 до 10000. Синтаксис пути в поле «Цель» проверяется при сохранении действия: некорректный путь отклоняется с ошибкой «Некорректный путь: ключи через точку, индексы массива в квадратных скобках не больше 10000 (например, items[2].name)». Путь в полях «Ключ в хранилище» элемента «Шаблон» и «Ключ результата в хранилище» элемента «AI-агент» проверяется при запуске процесса: с некорректным путём процесс не запускается.
  • Типы значений — в зависимости от операции в хранилище попадают строки, числа, объекты и массивы JSON. Операции «Записать строку» и «Добавить строку» всегда работают со строками; операции с суффиксом JSON сохраняют разобранную структуру.

Служебный ключ _loop заполняется движком процесса во время выполнения цикла. Не записывайте в _loop вручную правилами действий — используйте его только для чтения в шаблонах.

Правила обновления хранилища

Правила настраиваются в действии на вкладке «Обновление» в разделе «Обновление хранилища процесса». Они выполняются после успешного завершения действия, в порядке списка. Каждое следующее правило видит изменения, внесённые предыдущими правилами того же действия.

В конфигурации задачи процесса правила отображаются в режиме только для чтения; для изменения откройте действие из боковой панели задачи.

Поля правила

ПолеОбязательностьОписание
УсловиеНетGo-шаблон. Пустое значение — правило выполняется всегда. После рендеринга результат должен быть true, false, 1 или 0; иначе правило пропускается
ОперацияДаСпособ изменения значения по пути «Цель»
ЦельДаDot-path в хранилище без ведущей точки
ИсточникДа*Go-шаблон значения. Для операции «Удалить» не используется

Операции

ОперацияРезультат
Записать строкуЗаменить значение по пути текстовой строкой из источника; JSON не разбирается
Записать JSONЗаменить значение разобранным JSON (объект, массив, число, булево) из шаблона источника
Добавить строкуДописать текст к существующей строке по пути; если ключа нет — создаётся строка. Не применяется к числам и массивам
Добавить JSONДобавить один JSON-элемент в массив по пути; если массива нет — создаётся пустой массив
Слить JSON (поверхностно)Объединить JSON-объект из источника с объектом по пути: ключи верхнего уровня перезаписываются, вложенные объекты заменяются целиком
УдалитьУдалить ключ по пути

Для операций Записать JSON, Добавить JSON и Слить JSON источник должен давать корректный JSON: передайте значение через toJSON, например {{ toJSON .response.items }}. Если источник — один путь, например {{ .response.items }}, портал подставляет значение по этому пути без сериализации.

Примеры правил

Сохранить идентификатор из ответа действия:

УсловиеОперацияЦельИсточник
Записать строкуdeploy.job_id{{ .response.id }}

Записать массив для последующего цикла:

УсловиеОперацияЦельИсточник
Записать JSONnotification.engagements{{ toJSON .response.engagements }}

Дописать строку в лог:

УсловиеОперацияЦельИсточник
Добавить строкуrun.logstep {{ .store._loop.index }}: ok\n

Обновить только часть объекта:

УсловиеОперацияЦельИсточник
Слить JSON (поверхностно)meta{{ toJSON (dict "status" "ready" "updated_by" .entity.slug) }}

Выполнить правило только на первой итерации цикла:

УсловиеОперацияЦельИсточник
{{ .store._loop.first }}Записать строкуrun.started_at{{ now }}

Удалить временный ключ после использования:

УсловиеОперацияЦельИсточник
Удалитьtemp.payload

Панель «Контекст цикла»

В редакторе правил действия доступна панель Контекст цикла: она показывает ключи контекста цикла (_loop.item, _loop.index и др.). Нажмите на ключ, чтобы вставить его в правило.

Чтение из хранилища

В шаблонах процесса используйте:

{{ .store.<путь> }}

Для вложенных полей путь совпадает с «Целью» в правилах записи:

{{ .store.notification.module_name }}

Элемент массива читается функцией index:

{{ (index .store.items 0).id }}

Индекс в квадратных скобках, например items[0].id, работает только в путях записи, например в поле «Цель» правил записи. В Go-шаблоне такая запись завершит шаг с ошибкой.

Параметры запуска процесса доступны отдельным контекстом:

{{ .process.<идентификатор_параметра> }}

Подробнее о контекстах шаблонизации — в разделе «Шаблонизация».

Если ключа нет в хранилище (действие ещё не выполнялось, правило не сработало или условие было ложным), шаблон {{ .store.<путь> }} завершит шаг с ошибкой. Убедитесь, что предшествующие задачи записали нужные данные.

Контекст цикла _loop

Пока выполняется тело цикла, в хранилище доступен объект _loop:

КлючОписание
_loop.itemТекущий элемент коллекции (режим «По коллекции») или номер итерации, начиная с 1 (режим «Фиксированное число»)
_loop.indexИндекс итерации, начиная с 0
_loop.totalОбщее число итераций
_loop.firsttrue на первой итерации
_loop.lasttrue на последней итерации
_loop.parentКонтекст родительского цикла при вложенных циклах
_loop.loop_element_uuidUUID элемента «Цикл»

Примеры в шаблонах:

{{ .store._loop.item.name }}
{{ .store._loop.item.scan_type }}
{{ .store._loop.index }}

В условиях эксклюзивного шлюза внутри цикла:

{{ eq .store._loop.item.branch .store.current_branch_tag }}

Цикл по коллекции из хранилища

Элемент «Цикл» поддерживает два режима (поле «Режим цикла»):

  1. Фиксированное число — тело выполняется заданное количество раз (1–10000). В _loop.item — номер итерации (1, 2, 3…).
  2. По коллекции — при входе в цикл вычисляется Go-шаблон «Шаблон коллекции»; каждый элемент полученного JSON-массива — одна итерация. Массив может содержать до 10 000 элементов.

Шаблон коллекции

Рекомендуемый вариант — путь к массиву, уже записанному в хранилище предыдущей задачей:

{{ .store.notification.engagements }}

Альтернатива — собрать массив в шаблоне:

{{ toJSON .store.modules }}

Граничные случаи:

  • Пустой массив или отсутствующий ключ — 0 итераций, переход по связи «Выход из цикла»; в логе процесса появится предупреждение.
  • Строка, в которой записан JSON-массив, например результат правила «Записать строку» с источником {{ toJSON .response.items }}, разбирается как массив.
  • Значение по пути не является JSON-массивом — ошибка валидации или выполнения цикла.

Сценарий: обход списка из API

  1. Задача «Получить engagements» — правило Записать JSON, цель notification.engagements, источник {{ toJSON .response.engagements }}.
  2. Цикл, режим По коллекции, шаблон коллекции {{ .store.notification.engagements }}.
  3. Задача в теле цикла — в теле запроса использовать {{ .store._loop.item.id }}, {{ .store._loop.item.name }}.
  4. Эксклюзивный шлюз в теле — условие по полю элемента, например левое значение {{ .store._loop.item.status }}, правое active.
  5. Связь Выход из цикла — продолжение после обхода всех элементов.

Элемент «Шаблон»

Элемент «Шаблон» вычисляет Go-шаблон при проходе процесса и записывает строку в хранилище. JSON из результата не разбирается — в хранилище сохраняется текст как есть.

ПолеОписание
Тело шаблонаGo-шаблон; доступны {{ .store.* }}, {{ .process.* }}, внутри цикла — {{ .store._loop.* }}
Ключ в хранилищеDot-path назначения, например rendered_message или notification.summary
Подсказка форматаПодсказка при просмотре запуска (text, markdown, html, json); на запись не влияет

Пример тела:

## Отчёт по {{ .store._loop.item.name }}

Статус: {{ .store._loop.item.status }}
Владелец: {{ .store._loop.item.owner }}

Последующие задачи читают результат через {{ .store.rendered_message }} или соответствующий путь.

Просмотр хранилища при выполнении

На экране визуализации запуска процесса откройте вкладку Хранилище:

  • Дерево — навигация по вложенным ключам; справа — тип и значение выбранного узла.
  • JSON — полное содержимое хранилища в формате JSON.

Доступны копирование значения и обновление данных. Содержимое хранилища вместе с описанием запуска и логом скачивается кнопкой «Скачать диагностику» в окне запуска процесса.

В боковой панели задачи на схеме запуска отображаются Правила обновления хранилища выбранного действия. Сравните их с фактическим содержимым хранилища, чтобы найти правило, которое не сработало.

Лог процесса и отладка

На панели визуализации доступны:

  • Лог выполнения процесса — по умолчанию свёрнут под схемой и раскрывается кнопкой «Показать лог»; доступен также слева от схемы и в отдельном окне. Подробнее — в разделе «Лог процесса»;
  • Скачать диагностику — JSON-файл с описанием запуска, содержимым хранилища и полным логом;
  • сообщения о пустой коллекции цикла и пропущенных правилах хранилища.

При ошибке шаблона или невалидном JSON в правиле с операцией JSON соответствующее правило может быть пропущено (с предупреждением в логе), остальные правила того же действия продолжают выполняться.

Дополнительные ресурсы