Обработка сообщений — Handler и Action
После того, как смартап получил сообщение пользователя, в smart_kit.models.smartapp_model.SmartAppModel:answer
выбирается первичный порядок обработки этого сообщения (Handler). Обработка осуществляется в зависимости от поля MESSAGE_NAME
:
MESSAGE_TO_SKILL: HandlerText
Основные текстовые сообщения от пользователя, в которых голос распознается по ASR. HandlerText содержит в себе диалоговый менеджер, который вызывается для получения ответа для пользователя.RUN_APP: HandlerText
Сообщение о факте запуска навыка в интерфейсе или фразой "Запусти <название навыка>".SERVER_ACTION: HandlerServerAction
Служебное сообщение, адресованное навыку. Не является голосом или текстом.CLOSE_APP: HandlerCloseApp
Сообщение о закрытии навыка в интерфейсе.
Указанное соответствие MESSAGE_NAME-HANDLER
работает по умолчанию. Также есть возможность описать конкретное действие, зарегистрировав Action в Resourses.Responses
на определенный MESSAGE_NAME
(см. Action).
Это означает, что через выполнение Action или вызов Handler может быть обработан любой входящий запрос.
Обработка сообщений — DialogueManager
В диалоговом менеджере smart_kit.models.dialogue_manager.DialogueManager
существует развилка для обработки сообщения в зависимости от наличия сценария:
Если запущенного сценария нет, то происходит поиск и выполнение нового сценария в зависимости от интента из запроса пользователя.
Если запущенный сценарий есть и он соответствует интенту из запроса пользователя, то определяется, может ли фраза пользователя заполнить поля внутри форм текущего сценария:
- если сообщение пользователя не может заполнить ни одно поле этого сценария, то:
- обработка прекращается,
- возвращается ответ со служебным сообщением
NOTHING_FOUND
(см.smart_kit.system_answers.nothing_found_action.NothingFoundAction
).
- если поля внутри форм сценария заполнены, то происходит запуск (см.
static/references/scenarios
).
- если сообщение пользователя не может заполнить ни одно поле этого сценария, то:
Формат ответа и логирование
После того, как обработка запроса была завершена, сценарий возвращает ответ в виде набора команд, которые отправляются обратно пользователю. Формат ответа зависит от типа сценария:
Если сработал многошаговый сценарий, то в ответе от смартапа возвращается поле
payload.finished = False
для управления маршрутизацией следующего запроса. Этот запрос будет направлен в текущий смартап, если не сработает исключительное прерывание (команды навигации, стоп, текущее время и т.п.). Если сценарий продолжается и он ожидает от пользователя ответа, то в текущий ответ можно добавить полеauto_listening = True
. За счет этого на фронтенде будет активирован микрофон без срабатывания споттера или нажатия кнопки ассистента.Если сработал одношаговый сценарий, то сценарий возвращает
payload.finished = True
. Это означает, что сценарий ответил на вопрос пользователя и завершил свою работу.
Если в процессе обработки входящего сообщения приходят исключения, то ошибка будет залогирована. При этом для выдачи ответа пользователю будет выполнена команда excepion_action
из static/references/actions/actions.json
(см. Actions), в которой будет содержаться фраза о произошедшей ошибке.
Валидация сообщений
В SmartApp Framework есть абстрактный класс-валидатор MessageValidator
, с помощью которого можно валидировать входящие и исходящие сообщения. Из этого класса-валидатора тьюпл объектов передается в конструкторы классов входящего сообщения SmartAppFromMessage
и исходящего сообщения SmartAppToMessage
. Эти классы вызывают объекты класса-валидатора в методе validate()
.
Метод validate()
вызывается в объектах классов-наследников BaseMainLoop
при получении и перед отправкой сообщений.
В BaseMainLoop
валидаторы попадают через конструктор в виде двух тьюплов: для входящих (аргумент from_msg_validators
) и исходящих сообщений (аргумент to_msg_validators
) соответственно.
В свою очередь в BaseMainLoop
эти тьюплы попадают из app_config
, где опционально определяются константы FROM_MSG_VALIDATORS
и TO_MSG_VALIDATORS
.
По умолчанию во фреймворке нет конкретных валидаторов, и константы с ними содержат пустые значения. Вы можете определить свои классы-валидаторы с помощью наследования MessageValidator или использования плагина SAF JsonSchema, который предоставляет удобный валидатор JSON-Schema файлов с готовым набором схем.