Выкатываю новое расширение, мини-Jinja ака шаблонизатор для промптов. Требует последнего стейджинга, как всегда.
Как и обычная Jinja, поддерживает переменные, блоки и комментарии. Синтаксис пришлось немного сменить ({/} поменять на [/] и | на ->) из-за конфликтов с системой макросов таверны, но в целом логика та же. Переменных три вида:
- Переменные состояния - хранятся в сообщениях (в том же смысле, что и например во внешних блоках), так что изменения чата (откат/свайп/удаление сообщений) меняют значения этих переменных. При установке сохраняются в последнее сообщение. Доступны через
[[ var_name ]] - Локальные переменные - родные локальные переменные таверны (уникальные на чат), доступны через
[[ L.var_name ]]. - Глобальные переменные - родные глобальные переменные таверны (уникальные на таверны), доступны через
[[ G.var_name ]].
Также в таких скобках можно вычислять простые выражения с примитивами, типа[[ (1 + 2) * 3 ]].
Виды блоков:
- Условные - стандартные
[% if cond %][% elif cond %][% else %][% endif %]. Позволяют выполнять/вставлять что-то при определенных значениях переменных, например. - Циклы - стандартные
[% for item in array %][% endfor %]. Можно итерироваться по переменным/статическим массивам. - Назначения переменных -
[% set x = 10 %]для переменных состояния,[% set L.y = 20 %]для локальных,[% set G.z = 30 %]для глобальных. - Макросы - небольшие функции для переиспользования, доступны в том же рендере. Можно вызывать для повторяющихся вещей. Например:
[% macro bold(text) %]**[[ text ]]**[% endmacro %][[ bold("Hello World") ]] - Вероятностные блоки - вставляются только с определенным шансом. В elif синтаксисе броски кубика последовательные. Например:
[% chance 0.2 %]20% chance.[% elif 0.5 %]If first failed, 50% chance for this.[% else %]If all failed.[% endchance %] - Взвешенные блоки - блоки с распределением вероятности, для каждой записи задается вес, определяющий как часто запись будет вставляться в сравнении с другими. Например:
[% weighted %][% choice 10 %] Common (weight 10) [% endchoice %][% choice 1 %] Rare (weight 1) [% endchoice %][% endweighted %] - QR и ST скрипты - можно вызывать квикреплаи и одиночные слэш команды из шаблона. Важно: только вызывать, возвращать из них ничего не выйдет, вызов они тоже не блокируют. Примеры:
[% qr "Quick Reply name" %]для QR и[% st "setvar key=name some value" %]для ST скрипта.
В блоках можно контроллировать вайтспейсы вокруг с помощью -, как в Jinja, например[[ var -]]срежет все вайтспейсы справа.
Комментарии - стандартные [# comment #].
Для выражений также могут применяться фильтры, исходя из типа выражений. Фильтры пишутся через ->. Например [[ name -> upper -> wrap("(", ")") ]] переведет переменную name в высокий регистр и окружит ее скобками, если name непусто.
Шаблонизатор применяется автоматически к итоговому промпту на этапе, где уже применены родные макросы таверны, все собрано (пресет, чат, лорбуки) и после ноасса, так что он работает на все. Шаблонизатор также можно применить и вручную, через:
- Макрос
{{PromptTemplateEngine::<template>}} - Слэш команду
/PromptTemplateEngine-render <template>
Но сразу надо сказать, что ручное применение может быть ограниченным из-за конфликтов синтаксисов, так что надо осторожно.
Для переменных состояния тоже доступны макросы и слэш команды, как и для обычных переменных:
- Макросы
{{getstatevar::<name>}}и{{setstatevar::<name>::<value>}}для получения и установки - Слэш команды
/getstatevar <name>и/setstatevar key=<name> <value>для получения и установки
Надо отметить, что промпт менеджер не знает о существовании шаблонизатора и будет показывать завышенное число токенов и голый шаблон при нажатии на промпт, тут трудно чего-то поделать, не сломав безжопное расширение.
Также наверное надо с осторожностью применять шаблонизатор для карточек и лорбуков, потому что сторонние штуки, типа внешних блоков, будут получать нерендеренный шаблон. Интеграцию с внешними блоками я еще сделаю, но в том же QR вероятно это можно будет делать через костыли с ручным вызовом шаблонизатора.
Шаблонизатор, если что, не использует eval и сделан на AST дереве, так что его возможности в плане прав ограничены теми же, что и у ST скриптов.
Если чего ломается, пишите в тред.
Гит и чуть более подробно (из tests.js можно утащить еще примеров):
https://gitgud.io/Monblant/prompttemplateengine