Внешние блоки
Расширение для внешней генерации блоков (ST 1.12.0+)
Ссылка - https://gitgud.io/Monblant/extblocks
Установка: Extensions → Install extension (сверху справа) → Вставить ссылку https://gitgud.io/Monblant/extblocks
Обновление: Extensions → Manage extensions (сверху справа) → скролл вниз → кнопка обновить рядом с ExtBlocks
Краткое описание
Обозначения
- Блок - любая структура, ограниченная XML-тегами
<block_name>...</block_name>
- Основная сетка - API, которая используется для генерации основного ответа
- Дополнительная сетка - API и конкретная модель, которые используются для генерации блоков
Что делает
- Автоматически генерирует блоки по триггерам (отправленное сообщение юзера и/или пришедшее сообщение чара), сохраняет блоки в конфиге сообщений
- Позволяет использовать дополнительную сетку для генерации блоков с отдельными настройками
- Позволяет редактировать конфиг блоков и создавать пресеты блоков
- Позволяет встраивать конфиги блоков в карточку персонажа
- Автоматически создает регексы для блоков, которые скрывают их из основного промпта и из видимости (опционально)
- Позволяет инжектить блоки на глубину от роли юзера/чара или до/после системпромпта от роли системы
Зачем нужно
- Собственно генерировать блоки: например, инфоблоки или thinking
- Не засорять основной промпт инструкциями под блоки
- Работать в условиях присутствия стопстрингов (например, в случае ноасса)
- Использовать допсетки (не жечь ключ основной сетки, обходить рейтлимиты, использовать более быстрые и менее заточенные под писательство сетки)
- Использовать отдельные настройки апи и системпромта/префила для генерации блоков
- Гарантированная периодичность
- Отдельный промпт, отдельный контекст - лучшее исполнение инструкций, меньше потерь
- Раздельность генераций позволяет более эффективно работать с лорбуками
Виды блоков в расширении
- Генерируемый блок - блок, который генерируется сеткой
- Рерайтовый блок - генерируемый блок, который переписывает основной ответ
- Накопительный блок - блок, который обновляется исходя из появления блока-обновителя в основном ответе
- Скриптовый блок - блок, который выполняет код на STScript или JS. Если скрипт на JS, лучше почитать, что там написано, прежде чем его запускать.
Настройка
Расширение включается по кнопке Enable ExtBlocks
.
API допсетки
Настраивается в API Settings
:
- Выбирается
Chat Completion Source
и модель под него:- Для OpenAI: модели GPT и совместимые с OpenAI API
- Для MistralAI: модели Mistral
- Для Claude: модели Claude
- Для Gemini: модели Gemini
- Для OpenRouter: модели Hermes, LLaMa, Phi и LFM
- Под выбранную модель выбирается пресет прокси (для OpenRouter можно игнорировать).
- Опционально настраивается стриминг, температура, системпромпт и префил
Взаимодействие
Пресеты блоков и встроенные блоки
- Пресеты блоков расположены сверху в
ExtBlocks Preset
. Возможные операции с ними: создание нового, импорт из JSON, экспорт в JSON, удаление - Ниже в
Preset blocks
можно добавлять и импортировать из JSON конфиги блоков в пресет - Еще ниже в
Embedded blocks
можно добавлять и импортировать из JSON конфиги блоков в карточку персонажа. Конфиги блоков будут храниться в ней.
Редактирование блоков
Во вкладках Preset blocks
и Embedded blocks
можно выполнять операции с блоками: включать/выключать, редактировать, экспортировать в JSON, экспортировать промпт в JSON и удалять.
Накопительные блоки
В окне редактирования блоку можно задать:
- Имя - точное название блока без < и >
- Имя блока-обновителя - точное название блока без < и > (отличное от вышеупомянутого)
- Триггеры:
User Message
- блок будет обновляться исходя из сообщения юзераChar Message
- блок будет обновляться исходя из сообщения чара
- Состояние:
Disabled
- выключен ли блок (его генерация)Hide From Display
- нужно ли прятать блок из видимости для юзераInject block
- нужно ли вставлять блок в контекст основной генерации
- Настройки инжекта:
Injection Role
- роль инжекта (система, ассистент или юзер)Injection Position
:After Main Prompt
иBefore Main Prompt
- после/до мейнпромпта, корректно работает только с ролью системы. Мейнпромпт должен быть включен в пресете.In Chat
- на глубину в чат, корректно работает с ролями юзера и ассистента
Injection Depth
- глубина инжекта в чат. При отрицательных значениях вставляет блок на глубину с начала чата, при положительных - на глубину с конца.
Пример как должен выглядеть накопительный блок
У строк накопительного блока должна быть постоянная структура Свойство: Значение
Допустимы следующие типы значений: строка (в примере поле Name
), число (в примере поле Gold
) и массив (в примере поле Inventory
).
В массиве строки выглядят как Предмет: Количество предмета
(в примере строки Apple
и Sword
)
Note: Если предмет один, то можно писать просто Предмет
без двоеточия и количества (в примере - Map
).
Пример как должен выглядеть блок-обновитель
В блоке-обновителе поддерживаются несколько операций: присваивание (в примере поле Name
), сложение/вычитание для числовых значений (в примере поле Gold
), добавление/убирание предмета из массива (в примере поле Inventory
).
В сложении/вычитании нет пробела после +
, в добавлении/убирании - есть.
Генерируемые блоки
В окне редактирования блоку можно задать:
- Имя - точное название блока без < и >
- Тип - инжектовый или рерайт (о нем ниже)
- Шаблон блока
- Промпт блока
- Триггеры:
User Message
- блок будет генерироваться после сообщения юзера (также после нажатия на свайп, если чат был изменен)Char Message
- блок будет генерироваться после сообщения чара
- Периодичность - будет ли блок генерироваться с заданным периодом или по определенному кейворду.
- Период - расстояние между номерами сообщений. Например, если задан триггер
User message
, то чтобы блок генерировался каждое сообщение юзера, нужно задать период 2; каждое второе сообщение - период 4 и т.д. Нечетные периоды имеет смысл задавать только если включены оба триггера. - Кейворд - строка, при встрече в сообщении которой будет активироваться генерация блока.
- Состояние:
Disabled
- выключен ли блок (его генерация)Hide From Display
- нужно ли прятать блок из видимости для юзераInject block
- нужно ли вставлять блок в контекст основной генерации
- Настройки инжекта:
Injection Role
- роль инжекта (система, ассистент или юзер)Injection Position
:After Main Prompt
иBefore Main Prompt
- после/до мейнпромпта, корректно работает только с ролью системы. Мейнпромпт должен быть включен в пресете.In Chat
- на глубину в чат, корректно работает с ролями юзера и ассистента
Injection Depth
- глубина инжекта в чат. При отрицательных значениях вставляет блок на глубину с начала чата, при положительных - на глубину с конца.
- Контекст (правая часть редактора) - дополнительная информация для генерации. Доступны несколько видов контекста:
Text
- свободный текст, работают макросы таверныLast messages
- последние сообщения с возможностью прикрепления префиксов/суффиксов. При отрицательномMessages Count
выводятся первые сообщения.Last messages by keyword
- последние сообщения до встречи определенного кейворда. Полезно для кейворд-триггерных блоков.Previous block
- предыдущий блок.
- Порядок контекста изображен снизу справа, элементы можно передвигать вверх/вниз и удалять. Контекст можно импортировать и экспортировать. Блоки с одинаковым контекстом и триггером будут генерироваться в одной генерации (с учетом периода).
Итоговый промпт генерируемых блока/блоков, который отправляется на допсетку, будет выглядеть так:
- Склеенный контекст (через
\n
) \n
x 3- Склеенные шаблоны блоков (через
\n
) \n
x 2- Склеенные промпты блоков (через
\n
) - Отдельно системпромпт и префил (если Claude).
Пример корректной связки имя-шаблон-промпт для генерируемого блока:
Block Name:
current time
Block Template:
<current time>
Time of the day: HH:MM:SS
</current time>
Block prompt:
Write the current time of day in the <current time> block.
Рерайт блоки
Подвид генерируемых блоков, но они никуда не инжектятся - заместо этого они переписывают основной ответ. В редакторе для них есть дополнительный параметр Generation Order - контролирует когда блок будет перезаписывать сообщение, до или после генерации остальных блоков.
В шаблоне рерайт блоки должны содержать блок <rewritten text>
, остальное содержание ответа свободное. Имя блока может быть любым, в отличие от обычных генерируемых блоков.
Пример корректной связки имя-шаблон-промпт для рерайт блока:
Block Name:
basic rewrite
Block Template:
<rewritten text>
Rewritten text here
</rewritten text>
Block prompt:
Rewrite the given text.
Скриптовые блоки
В окне редактирования блоку можно задать:
- Имя - точное название блока без < и >
- Тип скрипта - STScript или JS
- Текст скрипта
- Триггеры, периодичность, состояние - как у генерируемых блоков
- Порядок выполнения - будет ли скрипт выполняться до или после генерации блоков
API для JS скриптов
Работа с STScript:
(async) executeST(text)
- выполняет STScript, подаваемый в функцию в виде строки
Получение блоков:
getAllBlocks()
- получает все блоки из текущего пресета и карточки в виде массива
getAllGeneratedBlocks()
- получает все генерируемые блоки из текущего пресета и карточки в виде массива
getAllRewriteBlocks()
- получает все блоки-переписыватели из текущего пресета и карточки в виде массива
getAllScriptBlocks()
- получает все скриптовые блоки из текущего пресета и карточки в виде массива
getAllEnabledBlocks()
- получает все включенные блоки из текущего пресета и карточки в виде массива
getPreviousBlockContextUnconditional(block, messageId, may_current, count)
- получает предыдущие состояния блока. Аргументы:
block
- блок, для которого получается состояниеmessageId
- старший номер сообщения, от которого будут искаться состояния блоковmay_current
- искать ли состояние блока в сообщении с номером messageId. Опциональный аргумент. Допустимые значения:true
,false
; по умолчанию -false
.count
- сколько нужно получить предыдущих состояний. Опциональный аргумент, значение по умолчанию - 1.
Работа с блоками:
(async) generateRewrite(rewriteBlock, messageId, allBlocks, additionalMacro)
- генерирует блок-переписыватель, возвращая строку. Аргументы:
rewriteBlock
- сам блок-переписывательmessageId
- номер сообщения, для которого генерируется блокallBlocks
- массив со блоками, которые релевантны для данного блока-переписывателя (либо просто со всеми блоками)additionalMacro
- дополнительные макросы в виде объекта с ключ - строковое значение, например{ fruit: 'apple' }
позволит воспользоваться в блоке макросом{{fruit}}
. Необязательный аргумент.
(async) handleRewriteBlocks(rewriteBlocks, generation_order, messageId, allBlocks, additionalMacro)
- генерирует блоки-переписыватели и переписывает заданное сообщение. Аргументы:
rewriteBlocks
- массив блоков-переписывателейgeneration_order
- фильтрует массив блоков-переписывателей относительно того, генерируются ли они до основных блоков или после. Допустимые значения:'before'
,'after'
messageId
- номер сообщения, для которого генерируются блокиallBlocks
- массив со блоками, которые релевантны для данных блоков-переписывателей (либо просто со всеми блоками)additionalMacro
- дополнительные макросы в виде объекта с ключ - строковое значение, например{ fruit: 'apple' }
позволит воспользоваться в блоке макросом{{fruit}}
. Необязательный аргумент.
(async) handleScriptBlocks(scriptBlocks, execution_order)
- выполняет скриптовые блоки. Аргументы:scriptBlocks
- массив со скриптовыми блокамиexecution_order
- фильтрует массив скриптовых блоков относительно того, генерируются ли они до основных блоков или после. Допустимые значения:'before'
,'after'
(async) generateBlockContent(blocksInGroup, messageId, allBlocks, additionalMacro)
- генерирует блоки, возвращая строку. Аргументы:
blocksInGroup
- массив генерируемых блоков с одинаковым контекстом (чаще всего массив из одного блока)messageId
- номер сообщения, для которого генерируются блокиallBlocks
- массив со блоками, которые релевантны для данных генерируемых блоков (либо просто со всеми блоками)additionalMacro
- дополнительные макросы в виде объекта с ключ - строковое значение, например{ fruit: 'apple' }
позволит воспользоваться в блоке макросом{{fruit}}
. Необязательный аргумент.
(async) handleGeneration(generatedBlocks, messageId, allBlocks, additionalMacro, is_separate)
- генерирует блоки и вставляет их в сообщение. Аргументы:
generatedBlocks
- массив генерируемых блоковmessageId
- номер сообщения, для которого генерируются блокиallBlocks
- массив со блоками, которые релевантны для данных генерируемых блоков (либо просто со всеми блоками)additionalMacro
- дополнительные макросы в виде объекта с ключ - строковое значение, например{ fruit: 'apple' }
позволит воспользоваться в блоке макросом{{fruit}}
. Необязательный аргумент.is_separate
- отвечает за то, будут ли блоки вставлены в сообщение с messageId, либо помещены в отдельное новое сообщение от роли системы. Допустимые значения:true
,false
; по умолчанию -false
.
(async) handleBlocksGeneration(messageId, isUser, allBlocks, triggeredBlocks, additionalMacro, is_separate)
- отвечает за обработку и генерацию всех блоков для заданного сообщения. Аргументы:
messageId
- номер сообщения, для которого обрабатываются блокиisUser
- идет ли сообщение от роли юзера. Допустимые значения: true, falseallBlocks
- массив со блоками, которые релевантны для обрабатываемых блоков (либо просто со всеми блоками)triggeredBlocks
- массив с блоками, которые будут обрабатыватьсяadditionalMacro
- дополнительные макросы в виде объекта с ключ - строковое значение, например{ fruit: 'apple' }
позволит воспользоваться в блоке макросом{{fruit}}
. Необязательный аргумент.is_separate
- отвечает за то, будут ли генерируемые блоки вставлены в сообщение с messageId, либо помещены в отдельное новое сообщение от роли системы. Допустимые значения:true
,false
; по умолчанию -false
.
injectBlock(block, blockConfig)
- вставляет состояние блока в основной контекст. Аргументы:
block
- состояние блока (строка)blockConfig
- конфигурация блока (объект)
Контекст расширения:
extStates
- константа-объект, хранящая состояния расширения. Имеет поля:
ExtBlocks_settings
- настройки расширенияcurrent_set
- текущий пресет блоковapi_preset
- текущий API пресетspoilerRegex
,self_reload_flag
иis_chat_modified
- технические значения
Контекст таверны:
context
- константа-объект, хранящая функции и состояния таверны. Определена в /public/scripts/st-context.js.
Примеры содержания скриптовых блоков:
- Генерация со вставкой блока
scene info
для последнего сообщения в чате:
- Генерация блока
profile
в виде строки и ее вывод в консоль браузера:
- Получение четырех предыдущих состояний блока
scene info
и вывод их в консоль браузера:
- Переписывание последнего сообщения с помощью блока
basic rewrite
, если в сообщении есть выражения-триггеры:
- Инжект последнего состояния блока
scene info
:
Инициализация блоков
Блоки можно инициализировать для новых чатов, добавив их в гритинг. Если блоки добавляются через редактирование нулевого сообщения, то чат нужно перезагрузить, чтобы блоки перешли в блоковое хранилище. Добавились ли блоки можно проверить, зайдя в редактирование сообщения после - их там не должно остаться.
Редактирование блоков в сообщении
Сгенерированные блоки хранятся в сообщениях, их можно редактировать. Нажимаете на три точки в сообщениях, ищите иконку карандаша на листе (скорее всего последняя кнопка), нажимаете на нее, открывается редактор. Редактируете блоки, сохраняете.
Слэш-команды
- Генерация блока/блоков -
/extblocks-generate
. Для команды неважно, включен ли блок. Аргументы:name
- имя блока/блоков, разделенных запятой, обязательный аргументis_separate
- при значении true блок создаст новое сообщение от роли системы, необязательный аргумент- неименнованный аргумент (ака текст после именованных аргументов) - дополнительный промпт. В промпте, шаблоне и контексте блока доступ к дополнительному промпту осуществляется через локальный макрос
{{additionalPrompt}}
- Перегенерация последних блоков -
/extblocks-regenerate
- Очистка инжектов -
/extblocks-flushinjects
- Добавление блока в хранилище блоков последнего сообщения -
/extblocks-storage-append
. Аргументы:- неименнованный аргумент - строка блока (переносы строк нужно заменить на
{{newline}}
, а|
на\|
).
- неименнованный аргумент - строка блока (переносы строк нужно заменить на
- Очищение хранилища блоков последнего сообщения -
/extblocks-storage-purge
. - Экспорт всех предыдущих блоков в системное сообщение (полезно при переносе чата) -
/extblocks-storage-export
- Вызов рерайт блоков -
/extblocks-rewrite
. Для команды неважно, включен ли блок. Аргументы:name
- имя рерайт блока/блоков, разделенных запятой, обязательный аргумент- неименнованный аргумент (ака текст после именованных аргументов) - дополнительный промпт. В промпте, шаблоне и контексте блока доступ к дополнительному промпту осуществляется через локальный макрос
{{additionalPrompt}}
- Выполнение скриптовых блоков -
/extblocks-execute-script
. Для команды неважно, включен ли блок. Аргументы:name
- имя рерайт блока/блоков, разделенных запятой, обязательный аргумент
Глобальные макросы
Макросы, которые можно применять везде.
- Доступ к прошлому блоку можно получить через макрос
{{extblock:имя_блока}}
Локальные макросы
Макросы, которые можно применять только в промпте, шаблоне и контексте генерируемого блока.
- Макросы лорбука (только постоянные и те, которые активируются на контекст+шаблон+промпт блока):
{{wiBefore}}
- записи лорбука с позицией ↑Char{{wiAfter}}
- записи лорбука с позицией ↓Char{{wiExamples}}
- записи лорбука с позицией ↑EM и ↓EM{{wiDepth}}
- записи лорбука с позицией @D{{wiAll}}
- все активированные записи лорбука
- Мейнпромпт текущего пресета -
{{mainPrompt}}
- Дополнительный промпт переданный через слэш-команду -
{{additionalPrompt}}
Известные проблемы
- Если выйти из режима редактирования сообщения через крестик, то блоки не будут показываться. Лечится выходом из режима редактирования через галку или входом-выходом чата.