Стейт-машина диалогов
Система многошаговых диалогов для мессенджеров. Позволяет строить интерактивные команды с ветвлениями, пагинацией и валидацией — через декларативный DSL, одинаковый для native- и WASM-плагинов.
Диаграмма классов
Граф узлов команды
Каждая команда — это дерево из CommandNode. При обработке ввода дерево линеаризуется в список активных шагов (flattenNodes) с учётом уже собранных параметров.
Жизненный цикл диалога
Хранение состояния
Состояние диалога хранится в Redis с ключом dialog:state:{GlobalUserID}. У каждого пользователя может быть один активный диалог.
┌──────────────────────────────────────┐
│ Redis key: dialog:state:42 │
│ TTL: 30 min (обновляется при Save) │
├──────────────────────────────────────┤
│ { │
│ "user_id": 42, │
│ "chat_id": "930733076", │
│ "command_name": "find", │
│ "params": { │
│ "what": "teacher", │
│ "building": "2" │
│ }, │
│ "page_state": { │
│ "building": 1 │
│ }, │
│ "created_at": 1711526400 │
│ } │
└──────────────────────────────────────┘Привязка к чату
ChatIDсохраняется при старте командыProcessInputигнорирует ввод из чужого чата (тихий пропуск, без ошибки)/resumeпереносит диалог в текущий чат черезRelocateDialog- Это позволяет начать команду в Telegram и продолжить в Discord (при связанных аккаунтах)