Skip to content

Latest commit

 

History

History
110 lines (74 loc) · 6.41 KB

DEV_PLUGINS.md

File metadata and controls

110 lines (74 loc) · 6.41 KB

Разработка плагинов

Для отладки можно использовать запуск системы через файл runva_cmdline.py.

Она делает запуск ядра (VACore in vacore.py) через интерфейс командной строки, это удобнее, чем голосом диктовать.

  • Подключить собственный навык можно, создав плагин в plugins_. Смотрите примеры.

Jaa.py

В целом, поддержка плагинов сделана на собственном движке Jaa.py - минималистичный однофайловый движок поддержки плагинов и их настроек.

Плагины располагаются в папке plugins и должны начинаться с префикса "plugins_".

Настройки плагинов, если таковые есть, располагаются в папке "options" (создается после первого запуска).

Типовые задачи

1. Простейший плагин

Пример самого простого плагина - plugins/plugin_greetings.py

Просто команда и её обработка

2. Плагин с пользовательскими настройками

Если нужно, чтобы юзер мог настроить плагин (например, задать apiKey для внешнего сервиса). Пример: plugins/plugin_yandex_rasp.py

Детали - в фреймворке Jaa.py.

(Если вдруг нужно сохранить пользовательские настройки после обработки плагином - гляньте plugins/plugin_weatherowm.py, там есть функция core.save_plugin_options(modname,options))

3. Плагин с кастомной обработкой пользовательских фраз

Все, что говорится после команды, будет передано в функцию плагина Например, если есть команда: "таймер", по фразе "ирина таймер пять" будет запущена def set_timer(core:VACore, phrase:str):, где phrase = пять

Пример: plugins/plugin_timer.py

4. Плагин с деревом команд

Команды можно задавать деревом.

Пример в plugins/plugin_random.py

"commands": { # набор скиллов. Фразы скилла разделены | . Если найдены - вызывается функция
            "подбрось|брось": { # если нашли - парсим дальше
                "монету|монетку": play_coin,
                "кубик|кость": play_dice,
            }
        }

5. Плагин с непрерывным взаимодействием (установлением контекста), или переспрашивающий

Обычно фразы должны начинаться с имени помощника (Ирина).

Но иногда хочется сделать красиво - например, если мы делаем голосовую игру, было бы странно каждый раз говорить Ирина. Или можно уточнить - "что там после слова таймер?"

Далее идет описание механизмов работы с контекстом /docs/DEV_CONTEXT.md

Простейшие примеры установления контекста для переспроса:

  • plugins/plugin_timer.py - таймер, в конце функции
  • plugins/plugin_mpchcmult.py - переспрос названия мультика

6. Плагин, устанавливающий голосовые команды в зависимости от пользовательских настроек

Пример: plugins_inactive/plugin_urlopener.py

7. Нечеткое распознавание команд пользователя

Пример - нечеткое распознавание название мультика в plugins/plugin_mpchcmult.py

# создаем список файлов в виде словаря
name_dict = {}
for f in mult_files:
    name = str(f)[:-4].lower().replace(".","").replace(",","")
    name_dict[name] = f

res = core.find_best_cmd_with_fuzzy(phrase,name_dict,False,0.7)
if res is not None: # найдено
    filename = name_dict[res[0]]
    print("Мульт ", filename)
    play_mult_direct(core, filename)
    core.say("Запускаю!")
    return

Параметры:

    def find_best_cmd_with_fuzzy(self,command,context,allow_rest_phrase = True,threshold:float = None):
        """
        Поиск оптимальной команды с учетом обработчиков нечеткого сравнения
        
        - command - команда
        - context - в формате Ирининого контекста (словарь {"cmd":"val",...}) - с элементами контекста будет сравниваться в поиске команды
        - allow_rest_phrase - дана ли в команде вся команда, или она может быть продолжена в контексте? не все нечеткие сравнители обрабатывают корректно
        Пример: 
        allow_rest_phrase=True: привет как дела -> привет (отлично подходит, будет вернута rest_phrase как дела)
        allow_rest_phrase=False: привет как дела -> привет (подходит не очень, будет вернута rest_phrase "")
        - threshold - в случае нечеткого сравнения - порог схожести (от 0.0 до 1.0). Если лучший результат сравнения ниже порога, результат не будет возвращен.
        Если None / не указано - будет браться из параметров core ядра Ирины.
        
        Возвращает tuple(key_in_context, схожесть (от 0.0 до 1.0), res_phrase)