Состояние
Типизированная память бота для пользователя, диалога, процесса или всего бота.
Состояние хранит небольшой объект между запусками обработчика. Платформа загружает его перед выполнением кода и сохраняет изменения после.
Используйте состояние для текущего шага, настроек и коротких флагов. Для списков, поиска и фильтрации подходят таблицы.
Области состояния
Область определяет владельца записи и срок её жизни.
| Область | Доступ | Пример |
|---|---|---|
| Пользователь | user.state | язык и настройки пользователя |
| Бот | bot.state | общий счётчик или флаг функции |
| Диалог | state в обработчике | текущий шаг диалога |
| Процесс | state в воркфлоу | прогресс долгой задачи |
Состояние пользователя доступно в его разных диалогах. Состояние диалога изолировано от остальных диалогов.
Объявление схемы
Схемы проверяют данные при чтении и записи. Значения default() применяются при
первом обращении.
import { z } from '@holocronlab/botruntime-runtime'
export const userState = z.object({
locale: z.string().default('ru'),
notificationsEnabled: z.boolean().default(true),
})
export const conversationState = z.object({
step: z.enum(['welcome', 'details', 'done']).default('welcome'),
})Подключите пользовательскую схему в agent.config.ts:
import { defineConfig, z } from '@holocronlab/botruntime-runtime'
import { userState } from './src/domain/state'
export default defineConfig({
name: 'my-bot',
user: { state: userState },
bot: { state: z.object({}) },
})Схему диалога передайте в Conversation:
import { Conversation } from '@holocronlab/botruntime-runtime'
import { conversationState } from '../domain/state'
export default new Conversation({
channel: '*',
state: conversationState,
handler: async ({ state, execute }) => {
if (state.step === 'welcome') state.step = 'details'
await execute({
instructions: `Продолжите диалог. Текущий шаг: ${state.step}.`,
})
},
})Отдельный вызов save() не нужен. Присваивайте новые значения напрямую.
Для вложенных объектов надёжнее заменить поле целиком. Так изменение будет однозначно видно механизму сохранения.
Ограничения
Состояние рассчитано на компактные объекты. Не храните в нём файлы и растущие массивы. Крупная запись может быть вынесена платформой во временный файл.
Не помещайте секреты в состояние. Для ключей и токенов используйте секреты конфигурации.
Низкоуровневый API
REST API адресует запись тройкой (type, id, name):
type—user,bot,conversation,workflowилиintegration;id— идентификатор владельца;name— имя записи.
API поддерживает чтение, полную запись, частичное обновление и атомарную операцию
get-or-set. Все запросы требуют Authorization: Bearer <bot-api-key>.
Список операций и актуальные схемы доступны в Chat API.
Срок жизни
Поле expiry задаёт время простоя в миллисекундах. Максимум — 30 дней. Значение
null отключает срок жизни.
После истечения платформа удаляет запись и отправляет событие state_expired.
Обработчик события должен быть идемпотентным: доставка выполняется как минимум
один раз.
Для бизнес-таймеров используйте фоновые процессы.
Состояние с expiry подходит для временных данных и коротких блокировок.
Что выбрать
| Задача | Механизм |
|---|---|
| Один компактный объект у пользователя или диалога | Состояние |
| Строки с фильтрами и сортировкой | Таблицы |
| Большой файл или база знаний | Файлы и знания |
| Долгая задача с ожиданием и повторными попытками | Фоновые процессы |