Выкатываю новое расширение, мини-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

Edit

Pub: 24 Dec 2025 12:25 UTC

Edit: 24 Dec 2025 12:46 UTC

Views: 34