Расширение → Import → включить блок. Для G-Block и Rewrite дополнительно настрой API и назначь батарейку.
Создавать новый G-Block не нужно. Подробности — в разделах 1–3.
Внешние блоки в SillyTavern: полный гайд
ExtBlocks — расширение SillyTavern для отдельных задач внутри чата. Оно позволяет генерировать текст со своим промптом и контекстом, переписывать сообщения целиком или частично, хранить и обновлять структурированные данные, выполнять STscript и JavaScript.
У генерируемых и накопительных блоков содержимое заключено в именованные теги, например <memory>…</memory>. Результат можно показывать в чате, скрывать, передавать основной модели или использовать в других блоках и скриптах. Через команду генерации его также можно вывести отдельным системным сообщением.
G-Block и Rewrite обращаются к модели через API-настройки ExtBlocks. Для них можно использовать ту же модель, что и в основном чате, или другие модели и подключения. A-Block обновляет данные по updater-командам без собственного запроса к модели. S-Block выполняет код и может запускать генерацию через команды или программные интерфейсы.
Для готового блока не нужно создавать новый блок вручную. Установи расширение, настрой подключение и импортируй файл — это шаги 1–3. Шаг 4 нужен тем, кто хочет сделать собственный блок.
Дальше разбираем все режимы и настройки: контекст, запуск, инъекцию, Rewrite, накопительные блоки, скрипты, команды и макросы. Можно идти по порядку или открыть нужный раздел через оглавление.
1. Устанавливаем и включаем расширение
Для расширения нужна SillyTavern 1.15.0 или новее.
В верхней панели SillyTavern открой Extensions / Расширения — это значок кубиков.
Нажми Install extension / Установить расширение.
Вставь ссылку:
Поле «Ветка или тэг» оставь пустым. Нажми «Установить только мне» и дождись завершения установки. «Установить для всех пользователей» нужно, если расширением должны пользоваться все аккаунты этой Таверны.
Если Таверна попросит обновить страницу — обнови.
В Расширения → Управление расширениями / Manage extensions проверь, что ExtBlocks есть в списке и возле него стоит галочка.
Закрой управление расширениями, найди раздел ExtBlocks в настройках расширений и раскрой его.
Поставь галочку Enable ExtBlocks — она включает работу блоков.
Установить расширение и добавить готовый блок — разные действия. Расширение устанавливается по ссылке, а сам блок обычно импортируется из файла .json.
2. Настраиваем модель для блоков
API — подключение к сервису, через который Таверна получает ответы модели. Connection Profile — сохранённый профиль этого подключения.
Эти настройки нужны G-Block и Rewrite, которые обращаются к модели. Для первого запуска можно использовать уже работающий профиль основного чата. Отдельное подключение пригодится, если для этой задачи нужна другая модель или другой сервис. A-Block и S-Block настраиваются по своей схеме в разделах 16–17.
Если хочешь отдельный профиль
- Открой API Connections / Подключение API — значок вилки в верхней панели.
- Вверху находится раздел «Профиль соединения». Запомни название текущего профиля: его потом нужно вернуть для ролки.
- Ниже выбери API → Chat Completion, нужный источник, модель, ключ и адрес подключения. Настрой всё так же, как для обычного чата.
- Возле списка профилей нажми лист с плюсиком — создание нового профиля. Назови его, например «Внешние блоки».
- Если после создания что-то меняешь, нажми дискету возле списка профилей, чтобы сохранить изменения.
Проверяем, что профиль сохранился
Открой список в разделе «Профиль соединения»: новое название должно быть в нём. Выбери профиль и нажми значок информации — кружок с i. В раскрытом списке проверь сохранённые API и модель.
Для проверки переключись на другой профиль, затем вернись к «Внешним блокам»: нужные настройки должны восстановиться. Сначала сохраняй изменения дискетой, потом переключайся.
Чтобы проверить само подключение, отправь короткое сообщение в отдельном чате и дождись ответа модели. Если ответ пришёл, подключение работает.
После проверки верни прежний профиль основного чата.
Подключаем профиль к ExtBlocks
Внутри расширения открой API Settings. Я обычно выставляю такие настройки:
| Поле | Что выбрать |
|---|---|
| API Preset | Medium |
| Connection Profile | Твой рабочий профиль или «Внешние блоки» |
| Temperature | 1 — как стартовое значение, если модель поддерживает |
| Top P | 1 — если модель поддерживает |
| Max Tokens | 4096 — лимит длины ответа блока |
Если новый профиль не появился в списке, нажми кнопку обновления рядом с Connection Profile.
Medium — это название набора настроек внутри ExtBlocks, а не конкретная модель. Реальная модель определяется выбранным Connection Profile. Big, Medium и Small можно настроить по своему усмотрению.
После добавления генерируемого блока назначь ему Medium через значок батарейки возле его названия. Нажатия переключают Big → Medium → Small. У Medium батарейка заполнена наполовину; на компьютере можно проверить подсказку API Preset: Medium. У A-Block и S-Block такой батарейки нет: им не назначается модель этим способом.
Просто выбрать Medium в API Settings недостаточно: отдельный блок может всё ещё использовать Big.
Генерация блоков тоже расходует токены. Более дешёвая модель может снизить расходы, но бесплатными блоки от этого не становятся. Если включён Inject Block, содержимое блока дополнительно передаётся основной модели и занимает место в её контексте.
3. Добавляем готовый блок, который скачали у автора
Сначала сохрани файл на устройство. Если это ZIP-архив, распакуй его и прочитай инструкцию автора: внутри могут быть несколько блоков и отдельные файлы оформления.
Если это один блок .json
- Открой Расширения → ExtBlocks.
- Вверху выбери нужный ExtBlocks Preset — набор, в котором будет храниться блок. Для первого раза можно оставить Default.
- Найди раздел Preset blocks.
- Нажми Import именно в этом разделе.
- Выбери скачанный файл
.json. На телефоне он обычно лежит в «Загрузках». - Убедись, что название блока появилось в списке и блок включён. Зачёркнутое название означает, что он выключен: нажми переключатель рядом с ним.
- Если возле блока есть батарейка, назначь ему настроенный API Preset, например Medium.
- Если автор дал дополнительные файлы или настройки, установи их по его инструкции.
Не нажимай + G-Block для импорта: эта кнопка создаёт новый пустой блок.
Если это целый набор / пресет ExtBlocks
Нажми значок импорта рядом с верхним списком ExtBlocks Preset, выбери файл набора и проверь, что нужный набор выбран. Его блоки появятся в Preset blocks.
Это другой импорт: верхняя кнопка предназначена для наборов, а Preset blocks → Import — для отдельных блоков.
Если блок нужен только одному персонажу
Открой чат с этим персонажем и используй Embedded blocks → Import. Блок будет сохранён в его карточке. В отличие от него, Preset blocks относится к выбранному набору расширения.
Если вместе с блоком дали regex-файл
Regex — отдельное правило, которое может превращать текст блока в красивое оформление. Такой файл импортируется в Regex / Регулярные выражения, а не в ExtBlocks. В зависимости от версии Таверны импорт находится в панели Regex или её редакторе.
Расширение .json само по себе не говорит, что лежит внутри: это может быть блок, набор или regex. Ориентируйся на подпись автора. Если файл не импортируется, сначала проверь, для какого раздела он предназначен. Экспорт одного только промпта тоже не является готовой конфигурацией блока.
После импорта сохрани авторские настройки шаблона, промпта, контекста и запуска, если в инструкции не сказано их менять. Для начала обычно достаточно подключить свою модель и включить блок.
4. Создаём свой первый блок вручную
Начнём со сводки текущей сцены: место, участники и происходящее. Красивое оформление можно добавить отдельно.
В разделе Preset blocks нажми + G-Block.
Коротко о типах: G-Block генерируется моделью; A-Block хранит состояние и обновляет его по специальным командам; S-Block выполняет скрипт. Для сводки нужен G-Block.
Название, шаблон и инструкция
Block Name — имя блока. Удобнее использовать латиницу и подчёркивания, например:
scene_info
Block Type — оставь Injectable. Режим Rewrite предназначен для переписывания ответа персонажа.
Block Template — образец структуры, которую должна вернуть модель. Он не обязан быть сложным HTML. Вставь:
<scene_info>
Место: ...
Участники: ...
Что происходит: ...
</scene_info>
Имя внутри открывающего и закрывающего тегов должно совпадать с Block Name.
Block Prompt — инструкция модели. Вставь:
По переданным сообщениям составь краткую сводку текущей сцены на русском языке. Укажи место, присутствующих участников и происходящее. Используй только установленные в переписке факты; если сведения неизвестны, напиши «неизвестно». Не придумывай действия, мысли и решения пользователя. Верни только блок <scene_info>...</scene_info> по указанному шаблону, без пояснений и без Markdown-ограждений.
Когда запускать генерацию
Чтобы блок появлялся после каждого ответа персонажа, выставь:
| Настройка | Значение |
|---|---|
| User Message | Выключено |
| Char Message | Включено |
| Generation Pause | Выключено |
| Trigger periodicity | Periodic |
| Period | 1 |
Так блок будет запускаться после каждого нового ответа персонажа, независимо от номера сообщения в чате.
Char Message означает запуск после ответа персонажа; User Message — после твоего сообщения. Periodic задаёт способ расчёта частоты, а не заменяет эти галочки.
В обычном чате, где сообщения пользователя и персонажа строго чередуются, Period 2 соответствует каждому ответу персонажа, 4 — каждому второму, 6 — каждому третьему. Но расширение считает номера сообщений всего чата, поэтому при другом порядке сообщений частота может отличаться. Для проверки надёжнее начать с Period 1 и одного включённого триггера.
Будет ли блок виден и будет ли модель его учитывать
В разделе State выставь:
| Галочка | Значение | Что означает |
|---|---|---|
| Disabled | Выключено | Блок работает |
| Hide From Display | Выключено | Блок виден в чате |
| Inject Block | Включено | Содержимое передаётся основной модели |
| Background Generation | Выключено | Обычная генерация |
Hide From Display и Inject Block отвечают за разные вещи. Скрытый блок может оставаться в контексте модели. Видимый блок может служить только тебе, если Inject Block выключен.
Если нужен только визуальный блок и основной модели он не нужен, отключи Inject Block.
При включённом Inject Block выбери Injection Role → System и Injection Position → After Main Prompt. Для этой позиции основной Main Prompt должен быть включён в пресете чата. Injection Depth здесь не нужен — он относится к позиции In Chat.
Даём модели сообщения для чтения
Теперь открой вкладку Context Builder. Здесь выбирается, что модель блока получит для работы. Один Block Prompt не заменяет контекст переписки.
- Нажми Add Item.
- Заполни поля:
| Поле | Значение |
|---|---|
| Context Item Type | Last messages |
| Item Name | Последние сообщения |
| Item Role | User |
| Messages Count | 6 |
| Messages Offset | 0 |
Здесь 6 — последние шесть несистемных сообщений чата, а не шесть пар «ты + персонаж». Item Name — имя элемента контекста; совпадение имён у разных блоков также влияет на объединение запросов, подробнее в разделе 14; Item Role задаёт роль контекста в запросе модели блока и не выбирает, чьи сообщения читать.
- Остальные поля пока оставь по умолчанию.
- Нажми Save Item, затем Save, чтобы сохранить весь блок.
- В списке блоков назначь ему Medium через батарейку.
Можно добавить ещё один Item типа Previous block, если блоку нужно читать свой предыдущий результат — например, чтобы продолжать сводку. Укажи Block Name → scene_info, Blocks Count → 1, придумай Item Name и сохрани Item. Добавляй этот Item, только если блоку нужен его прошлый результат.
Другие типы контекста: Text — текст, который ты впишешь вручную; Last messages by keyword — сообщения, отбираемые с учётом заданного ключевого слова. Для первого запуска достаточно обычного Last messages.
5. Какие блоки бывают и что с ними можно сделать
В ExtBlocks есть три кнопки создания, но четыре режима работы: Rewrite выбирается внутри редактора G-Block.
| Тип | Что делает | Для чего пригодится | Кто выполняет работу |
|---|---|---|---|
| G-Block → Injectable | Генерирует отдельный блок | Память, анализ переписки, планирование, дневник, варианты действий, текст и данные для других блоков | Модель из API Preset |
| G-Block → Rewrite | Переписывает текст сообщения | Перевод, исправление языка, изменение стиля, сокращение или доработка выбранного фрагмента | Модель из API Preset |
| A-Block | Хранит данные и применяет к ним обновления | Состояние мира, персонажей и игровых систем: флаги, счётчики, инвентарь, задания, отношения | Расширение; команды обновления пишет модель или ты |
| S-Block | Выполняет скрипт | Автоматизация, команды, вычисления, связки с другими функциями Таверны | STscript или JavaScript |
G-Block удобен, когда каждый раз нужен новый текст. A-Block — когда важно сохранить структуру данных и изменить только отдельные значения. S-Block — когда нужны действия, а Rewrite — когда нужно поменять уже полученный ответ.
Например, можно собрать такую связку: A-Block хранит инвентарь → G-Block читает инвентарь и последние события → возвращает команды обновления → A-Block применяет их. Другой G-Block делает красивое описание состояния, а S-Block запускает нужные команды.
S-Block может связывать блоки с командами и функциями SillyTavern: например, запускать генерацию, читать сохранённое состояние или выполнять вычисления. Поиск, создание изображений и другие внешние действия зависят от подключённых инструментов и выполняемого скрипта. Для визуального оформления текста можно использовать HTML, CSS и regex.
Примеры задач
- Память и анализ — Обновлять долгую сводку, выделять факты и противоречия, разбирать мотивы персонажей. Результат можно хранить скрыто и передавать в следующие запросы.
- Планирование и творческий текст — Готовить варианты развития сцены, записи дневника, реплики рассказчика или вспомогательные заметки по заданному контексту.
- Перевод и редактура — Через Rewrite переводить ответ, менять его стиль, сокращать или дорабатывать выбранный абзац.
- Состояние и механики — Через A-Block хранить структуру данных и менять отдельные значения: от ресурсов и инвентаря до флагов событий и отношений.
- Связки и автоматизация — Через S-Block запускать команды, обращаться к данным блоков и функциям Таверны. G-Block может, например, подготовить промпт, который затем использует настроенное расширение генерации изображений.
Конкретное поведение задают промпт, контекст, триггеры и код конфигурации. Блоки из каталога Шино — готовые примеры таких настроек; собственные задачи можно собрать теми же средствами.
6. Пресеты, встроенные блоки и кнопки панели
Три разных «пресета»
Здесь легко запутаться, поэтому сразу разделим названия.
| Название | Что это | Где находится |
|---|---|---|
| ExtBlocks Preset | Набор конфигураций блоков | Верхний список в ExtBlocks |
| API Preset: Big / Medium / Small | Настройки запросов к модели для блоков | API Settings и батарейка блока |
| Пресет основного чата | Основные промпты и настройки ролки | Обычные настройки SillyTavern |
Переключить набор ExtBlocks и переключить модель блока — разные действия. Набор может содержать блоки с разными батарейками.
Работа с наборами
Возле ExtBlocks Preset находятся кнопки создания, импорта, экспорта и удаления набора. Чтобы собрать отдельный набор, нажми +, дай ему понятное имя и добавь нужные блоки в Preset blocks. Для другой ролки можно создать другой набор и переключаться между ними.
Экспорт набора сохраняет его блоки и их конфигурации. Он не переносит твои ключи, рабочее подключение и всю историю результатов из чата. После импорта на другом устройстве проверь API Settings и батарейки.
Импорт набора с уже существующим именем может заменить набор с этим именем. То же относится к импорту одноимённого блока в его раздел. Перед заменой своей настроенной версии сохрани её экспортом.
Preset blocks и Embedded blocks
Preset blocks принадлежат выбранному набору. Embedded blocks записываются в карточку конкретного персонажа и могут переезжать вместе с ней, если формат экспорта сохраняет данные расширений.
Одновременно используются блоки выбранного набора и карточки. Если в обоих разделах есть блок с одинаковым Block Name, приоритет получает Embedded block. Это действует даже тогда, когда встроенный блок выключен: одноимённый блок из набора не становится его запасной версией.
Если блок ведёт себя не так, как настроено в Preset blocks, проверь, нет ли одноимённого в Embedded blocks. Для независимых блоков используй разные имена.
Кнопки возле блока
| Кнопка | Что делает |
|---|---|
| Полоски слева | Перетаскивание и изменение порядка |
| G / R / A / S | Тип блока |
| Батарейка | Big → Medium → Small для G и Rewrite |
| Переключатель возле имени | Включение и выключение; выключенное имя зачёркнуто |
| Карандаш | Редактор конфигурации |
| Документ со стрелкой | Экспорт готовой конфигурации блока в JSON |
| Волшебная палочка | Экспорт собранного запроса G / Rewrite для текущего чата |
| Корзина | Удаление конфигурации |
Экспорт блока нужен, чтобы поделиться работающей настройкой. Экспорт промпта показывает, какой запрос получается после сборки контекста и подстановок. Для него должен быть открыт чат; такой файл может содержать фрагменты переписки. Он не заменяет файл блока для импорта.
Перетаскивание меняет порядок внутри списка, но не превращает разные типы блоков в произвольную цепочку. Для S-Block и Rewrite дополнительно важны их настройки Before / After.
Быстрый доступ
В меню расширений возле поля ввода есть пункт ExtBlocks. Он открывает ту же панель в отдельном окне: можно переключить набор, настроить API и открыть редактор блока без перехода к верхней панели. Настройки общие для обоих способов открытия.
7. API Settings: все параметры
Для запросов ExtBlocks нужен сохранённый профиль Chat Completion. Основной чат при этом может пользоваться другим подключением.
| Поле | Что означает | Как выбирать |
|---|---|---|
| API Preset | Какой набор настроек сейчас редактируешь | Настрой каждый используемый Big / Medium / Small |
| Connection Profile | Профиль, из которого берутся источник, модель и подключение | Выбери сохранённый рабочий профиль с уникальным именем |
| Кнопка обновления списка | Повторно загружает список профилей | Нажми после создания или переименования профиля |
| Stream | Получение ответа API частями | Это режим запроса; он не гарантирует постепенный показ блока в чате |
| Temperature | Разнообразие ответа | Для фактов и YAML обычно удобнее более низкая; для творческого текста можно выше |
| Top P | Ещё один параметр выбора продолжения | Для начала можно оставить 1, если сервис его поддерживает |
| Max Tokens | Максимальная длина ответа API | Должно хватить на весь результат и закрывающие теги |
| Reasoning Effort | Запрашиваемый уровень рассуждения | Auto или поддерживаемое моделью значение |
| Enable confirmation JB | Добавляет в конец запроса пару реплик с просьбой подтвердить запрос и подтверждением | Не требуется для обычной настройки; не гарантирует принятие запроса моделью |
В Reasoning Effort доступны Auto, Low, Medium, High, Min и Max. Наличие пункта в списке не означает, что выбранная модель его поддерживает. Сервис может проигнорировать параметр или вернуть ошибку.
Max Tokens — не размер памяти блока. Сколько переписки он увидит, определяет Context Builder. У некоторых моделей лимит ответа также включает токены рассуждений, поэтому видимый текст может оказаться короче.
Big, Medium и Small не означают «дорого», «средне» и «дёшево» автоматически. Можно выбрать, что к ним подключить. Можно назначить одну модель всем трём и отличать их только параметрами.
Новый G-Block обычно получает Big. Назначай нужную батарейку после создания или импорта. У A-Block и S-Block модели нет, но скрипт может самостоятельно вызывать команды генерации.
Если профиль удалён или переименован, перепроверь Connection Profile: расширение связывает его по имени и при отсутствии совпадения может обратиться к другому доступному профилю. Не создавай несколько профилей с одинаковыми именами.
Для Custom / OpenAI-совместимого подключения проверь сохранённый URL API, выбранную модель, ключ и дополнительные поля, которые нужны твоему сервису. Включённый профиль без URL не станет рабочим подключением.
8. G-Block: шаблон, промпт и формат ответа
Редактор состоит из двух вкладок: Block Settings и Context Builder. В первой мы описываем задачу и поведение блока, во второй — данные для её выполнения.
| Поле | Зачем нужно |
|---|---|
| Block Name | Имя, по которому блок сохраняется, находится в командах и связывается с другими блоками |
| Block Type | Injectable или Rewrite |
| Block Template | Требуемая структура результата |
| Block Prompt | Инструкция модели: что сделать и как заполнить структуру |
Я советую короткие имена вроде scene_info, world_news, inventory_update. В одном разделе имя должно быть уникальным. Если переименовываешь блок, проверь его теги, Previous block, макросы, команды и regex: связанные настройки сами за новым именем не переедут.
Что писать в Template
Внешние теги позволяют расширению распознать результат. Внутри может быть обычный текст, Markdown, HTML или YAML — по задаче блока.
<world_news>
1. ...
2. ...
3. ...
</world_news>
Для Injectable внешнее имя должно совпадать с Block Name. Не проси модель возвращать пояснение вместо блока: результат без нужных тегов может не попасть в хранилище.
Сам шаблон не является движком вёрстки и не заполняет многоточия автоматически. Модель получает его как образец. Если шаблон сложный, подробно объясни, какие части сохранять и какие значения менять.
Что писать в Prompt
Хорошая инструкция отвечает на четыре вопроса: какие данные использовать, что получить, чего не выдумывать и в каком формате вернуть ответ.
Составь три короткие новости мира по переданным сведениям.
Не противоречь установленным событиям и не решай за пользователя.
Если достоверных событий недостаточно, укажи это вместо выдуманных фактов.
Верни только <world_news>...</world_news>, без вступления и Markdown-ограждений.
{{additionalPrompt}}
Последняя строка позволяет передать дополнительную просьбу через команду запуска. Если такой подстановки нет ни в промпте, ни в шаблоне, ни в контексте, дополнительная просьба не попадёт в запрос.
Чего блок не видит автоматически
Отдельная модель не получает весь основной промпт, карточку, лорбук и чат просто потому, что они открыты в Таверне. Нужную информацию добавляем через Context Builder и макросы. Если блок придумывает прошлое сцены, сначала проверь его входные данные.
9. Запуск: сообщения, период и ключевые слова
Есть две части настройки: событие запуска и условие запуска.
| Событие | Когда используется |
|---|---|
| User Message | После сообщения пользователя; также участвует в обработке новых свайпов |
| Char Message | После ответа персонажа |
| Generation Pause | При появлении маркера во время потокового ответа персонажа |
Можно отметить User Message и Char Message одновременно, но тогда блок может запускаться дважды за обмен репликами. Для сводки после ответа достаточно Char Message.
Periodic
Period 1 — на каждом выбранном событии. Это удобное значение для первого запуска.
Дальше расширение ориентируется на номер сообщения в общем массиве чата. В обычном чередовании с приветствием под номером 0 ответы персонажа имеют номера 2, 4, 6 и так далее.
| Period при Char Message | В обычном чередующемся чате |
|---|---|
| 1 | Каждый ответ |
| 2 | Каждый ответ с чётным номером — обычно тоже каждый ответ |
| 4 | Обычно каждый второй ответ |
| 6 | Обычно каждый третий ответ |
У User Message проверка сдвинута на один номер. Дополнительные системные сообщения, удаление реплик и другой порядок разговора меняют расчёт. Period 3 не означает универсально «раз в три ответа». Используй положительное целое число; 0 не задаёт режим «всегда».
Keyword-based
В Trigger periodicity выбери Keyword-based и заполни Keyword. Блок запустится, когда выбранное сообщение содержит нужный текст.
Например: User Message включено, Keyword — [новости]. Отправляешь сообщение с этим маркером — блок срабатывает. Без Regex это обычный поиск подстроки с учётом регистра.
С галочкой Regex можно задать регулярное выражение:
/\[новости\]/i
Здесь i разрешает разные варианты регистра. Скобки экранированы, потому что в регулярном выражении они имеют специальное значение. Неверное выражение не даст ожидаемого запуска.
В Keyword-based частоту задаёт совпадение Keyword, а не старое значение Period. Пустое ключевое слово не годится для настройки такого запуска.
Keyword в триггерах определяет, когда запускать блок. Keyword Stopper в Context Builder определяет, какую часть переписки читать. Это разные поля.
Ручной запуск
Можно оставить автоматические события выключенными и запускать G-Block по имени:
/extblocks-generate name="scene_info"
Команда по имени может вызвать даже блок с Disabled. Disabled выключает автоматическую работу, но не является запретом на явный вызов командой.
10. Generation Pause: блок посреди ответа
Этот режим нужен, когда персонаж должен сначала дойти до определённого момента, затем получить результат внешнего блока и продолжить.
- Включи потоковый ответ основного чата.
- В блоке отметь Generation Pause. Редактор переключит условие на ключевое слово.
- Задай уникальный Keyword, например
[ПРОВЕРКА_СЦЕНЫ]. - В основном промпте объясни, когда модель должна выдавать этот маркер.
- Настрой контекст внешнего блока и нужную инъекцию результата.
Когда маркер появляется в потоке, расширение останавливает ответ, обрезает продолжение после точки остановки, запускает нужные блоки и затем инициирует продолжение генерации. Маркер при обычном поиске и при Regex может сохраняться в тексте по-разному.
Не используй частое слово вроде «да»: остановка должна происходить в конкретном месте. При продолжении модель может повторить маркер и вызвать новую паузу, поэтому в инструкции укажи, что после получения результата этот маркер повторять не нужно.
Stream в API Settings ExtBlocks и потоковый ответ основного чата — разные настройки. Для обнаружения маркера важен поток основного ответа. Результат после паузы зависит и от того, как основной пресет настроен на продолжение.
11. State: видимость, инъекция и фон
| Настройка | За что отвечает |
|---|---|
| Disabled | Выключает блок из обычной автоматической обработки |
| Hide From Display | Скрывает показ результата в чате |
| Inject Block | Передаёт последнее доступное состояние основной модели |
| Background Generation | Запускает обычный G-Block в фоне, не дожидаясь его в общей цепочке |
Как совместить Hide и Inject
| Hide From Display | Inject Block | Что получится |
|---|---|---|
| Выключено | Выключено | Видимый результат для чтения или оформления |
| Выключено | Включено | Результат виден и передаётся основной модели |
| Включено | Включено | Скрытая память или состояние для модели |
| Включено | Выключено | Результат хранится для других блоков, макросов или скриптов |
Для последнего варианта нужно, чтобы результат кто-то действительно читал: например, через Previous block.
Background Generation
Фоновый блок сохраняет результат после завершения своего запроса. Следующий скрипт или другой запрос может начаться раньше и увидеть старое состояние.
Фон удобен для необязательной панели, которая может обновиться чуть позже. Для блока, от которого зависит следующий шаг, лучше обычная генерация. Особенно это касается G-Block с командами обновления A-Block: общая цепочка обрабатывает результаты, которых она дождалась.
У A-Block нет фоновой генерации, у S-Block из State есть Disabled. Rewrite выполняется в своём порядке Before / After; его нельзя превратить в фон обычного G-Block одной галочкой.
12. Injection: что попадёт в основной запрос
Инъекция работает для обычных G-Block и A-Block. В основной запрос попадает содержимое последнего подходящего сохранённого блока, а не вся история его версий.
Injection Role
| Роль | Как выглядит содержимое в запросе |
|---|---|
| System | Системное сообщение с данными или инструкцией |
| User | Сообщение пользователя |
| Assistant | Сообщение ассистента |
Роль не делает сведения истинными и не задаёт, чьи сообщения блок прочитает. Она определяет место содержимого в структуре запроса основной модели. Для состояния сцены удобно начать с System.
Injection Position
| Позиция | Где размещается содержимое |
|---|---|
| After Main Prompt | После основного Main Prompt |
| Before Main Prompt | Перед основным Main Prompt |
| In Chat | В части запроса с историей сообщений |
Before / After Main Prompt предназначены для System; основной Main Prompt должен быть включён в пресете. Для User / Assistant используй In Chat.
Injection Depth
Depth относится к In Chat и задаёт глубину вставки относительно конца истории. Маленькое неотрицательное значение размещает блок ближе к свежим сообщениям; большее — глубже. Начни с 0–4 и проверь итоговый запрос в Таверне.
Поле допускает отрицательные числа, но для обычной настройки лучше их не использовать: расширение пересчитывает отрицательную глубину через длину чата, поэтому это не удобный способ задать стабильную позицию у начала.
Если блок запускается после ответа персонажа, этот ответ уже был написан без его нового результата. Свежая инъекция пригодится следующей генерации. Для данных, которые нужны до текущего ответа, выбирай User Message или продуманную схему Generation Pause.
Видимость, инъекция и отдельное системное сообщение через is_separate=true — три разных механизма. Последний действительно добавляет новую реплику в историю чата.
13. Context Builder: как собрать входные данные
Item — один источник информации в запросе модели блока. Их может быть несколько: правила в Text, переписка в Last messages, прошлое состояние в Previous block.
| Общая настройка | Что означает |
|---|---|
| Context Item Type | Тип источника данных |
| Item Name | Имя элемента; выбирай понятное и различающее нужные контексты |
| Item Role | Роль всего элемента в запросе модели блока |
| Save Item | Сохраняет изменения элемента в редакторе |
| Save | Сохраняет всю конфигурацию блока |
Item Role → User не означает «читать только мои сообщения». Если тип — Last messages, он берёт и пользователя, и персонажа; роль назначается собранному тексту.
Элементы можно включать и выключать, редактировать, удалять и переставлять. Они собираются в порядке списка; соседние элементы одной роли могут объединяться в одно сообщение API.
Кнопки импорта и экспорта возле Context Items работают со всем набором элементов контекста. Импорт заменяет текущий список Items в редакторе, поэтому сначала сохрани нужную конфигурацию. Файл контекста не является готовым блоком.
Text
В Content впиши постоянный текст: описание задачи, данные персонажа, правила мира или значения для подстановки. Можно использовать обычные макросы SillyTavern вроде {{user}} и {{char}}, а также макросы ExtBlocks.
Пользователь: {{user}}
Персонаж: {{char}}
Правило: не добавляй в сводку события, которых нет в переданных данных.
Имена {{user}} и {{char}} подставляют имена, а не полную карточку персонажа или персоны. Если нужны дополнительные сведения, добавь их отдельно.
Last messages
Берёт последние доступные сообщения до точки запуска включительно. Обычные сообщения пользователя и персонажа учитываются вместе; сообщения с системным флагом исключаются.
| Поле | Что делает | Пример |
|---|---|---|
| Messages Count | Сколько сообщений взять | 6 — последние шесть реплик, не шесть пар |
| Messages Offset | Сколько последних реплик пропустить | Count 6 + Offset 2 — шесть реплик перед последними двумя |
| Messages Separator | Разделитель реплик | Double newline — пустая строка между ними |
| User Prefix / Suffix | Текст до / после каждой реплики пользователя | {{user}}: |
| Char Prefix / Suffix | Текст до / после каждой реплики персонажа | {{char}}: |
Префиксы помогают различать участников, особенно если весь Item отправляется с одной ролью. Можно писать \n для переноса строки: редактор превращает его в настоящий перенос.
Отрицательный Messages Count имеет отдельный смысл: -3 берёт первые три доступные несистемные реплики. Это может пригодиться для начала истории. Чтобы отключить Item, используй его переключатель: значение 0 при сохранении редактор может заменить стандартным числом.
Last messages by keyword
Здесь Keyword Stopper — маркер границы контекста. Расширение ищет его в предыдущих сообщениях и берёт переписку от последнего найденного маркера до точки запуска. Сообщение с маркером тоже входит в контекст.
Например, в начале новой сцены пишешь [НОВАЯ_СЦЕНА]. Такой Item помогает ограничить вход текущей сценой.
Это обычный поиск подстроки с учётом регистра, отдельной галочки Regex у Stopper нет. Самое свежее сообщение не используется как предыдущая граница при обычном поиске. Если маркер не найден, берётся переписка с начала: контекст может внезапно стать большим.
Previous block
Берёт сохранённые результаты названного блока из предыдущих сообщений.
| Поле | Что заполнить |
|---|---|
| Block Name | Точное имя существующей конфигурации без угловых скобок |
| Blocks Count | Число прошлых результатов; для последнего состояния обычно 1 |
Название Item Name — подпись самого источника. Block Name — имя блока, результат которого нужен. Они не обязаны совпадать.
Previous block не запускает другой блок заново. При первом запуске прошлой версии может ещё не быть. В обычном Item поиск идёт по предыдущим сообщениям, поэтому это не способ гарантированно прочитать результат соседнего блока, созданный только что у той же реплики.
Для памяти удобно соединить Text с правилами + Previous block со старой сводкой + Last messages с новыми событиями. В промпте попроси обновить сводку, сохранив действующие факты и убрав устаревшие.
Необязательный контекст и пустые данные
Выключенные и пустые Items не добавляются в запрос. Если Previous block пуст на старте, объясни модели, что это нормальная ситуация. Не заставляй её выдумывать прошлое состояние, которого ещё нет.
14. Несколько G-Block и общий запрос
Расширение умеет объединять обычные генерируемые блоки в один запрос: модель получает несколько шаблонов и инструкций сразу. Это может сократить повторную отправку одинакового контекста.
Для объединения учитываются имена Context Items и их порядок, а также фоновый режим. При этом запрос использует контекст и API Preset первого блока в группе. Одного совпадения подписей недостаточно, чтобы данные в двух блоках действительно были одинаковыми.
Поэтому Item Name влияет не только на удобство чтения списка:
- Если блоки должны использовать один и тот же контекст и модель, оставь одинаковую последовательность имён Items и одинаковые настройки данных.
- Если нужны разные модели или разный контекст, дай Items разные имена: например,
scene_recentиnews_recent. - Если у нескольких блоков совсем нет Items, они тоже могут попасть в одну группу.
После этого проверь батарейки и экспорт полного промпта. Не рассчитывай на отдельную модель каждого блока, если их контексты объединяются.
У группы общий Max Tokens на весь ответ, включая все блоки. Если модель успела вернуть только первый и оборвала следующий, увеличь лимит или раздели запросы.
Объединённые блоки не генерируются один за другим внутри одного запроса. Если одному нужен свежий результат другого, нужна отдельная последовательность запуска; Previous block обычно читает прошлые сообщения.
15. Rewrite: переписывание ответа или фрагмента
Rewrite — режим G-Block, который заменяет текст сообщения результатом другой модели. Можно поправить язык, сократить текст, изменить стиль или доработать отдельный абзац.
Создаём блок
- Нажми + G-Block.
- Задай Block Name → polish_text.
- Выбери Block Type → Rewrite.
- Вставь в Block Template:
<rewritten text>
...
</rewritten text>
У Rewrite специальный обязательный тег <rewritten text>, независимо от Block Name. Здесь не используем <polish_text> как тег результата.
В Block Prompt:
Перепиши переданный текст на русском языке: исправь ошибки и неестественные обороты.
Сохрани факты, действия, точку зрения и смысл. Не добавляй действия пользователя.
Верни только <rewritten text>...</rewritten text>.
{{additionalPrompt}}
В Context Builder добавь Text, роль User, Content:
Текст для переписывания:
{{textToRewrite}}
Сохрани Item и блок, назначь батарейку. {{textToRewrite}} передаст целое сообщение или выбранный фрагмент в зависимости от способа вызова.
Ручной и автоматический режимы
Для ручной обработки последнего сообщения выключи User Message, Char Message и Generation Pause. Запуск:
/extblocks-rewrite name="polish_text"
Для автоматической обработки ответа включи Char Message, Period 1. В Generation Order выбери:
| Порядок | Когда переписывается сообщение |
|---|---|
| Before blocks | Перед обычными G-Block: они смогут читать уже изменённый текст |
| After blocks | После обычных G-Block: они работают с исходным ответом |
Если несколько Rewrite сработали вместе, они выполняются последовательно. Это несколько запросов и несколько изменений одного сообщения.
Переписываем выделенный фрагмент
- Включи нужный Rewrite-блок: список выбора показывает включённые Rewrite.
- Открой обычное редактирование сообщения персонажа.
- Нажми кнопку [ExtBlocks] Partial rewrite в редакторе сообщения.
- Выдели текст в поле редактирования.
- В появившемся окне выбери блок, при необходимости впиши дополнительную просьбу и запусти Rewrite.
Дополнительная просьба попадёт в модель через {{additionalPrompt}}. Возможность выделения зависит от интерфейса устройства; если окно не появляется на телефоне, можно обработать целое последнее сообщение командой.
Rewrite меняет сохранённое сообщение. Если исходная версия нужна, сохрани её перед обработкой. При одинаковых повторяющихся фрагментах замена может затронуть первое совпадение текста.
16. A-Block: состояние, инвентарь и счётчики
Накопительный блок хранит структуру в YAML и меняет её по командам обновления. Он не вызывает свою модель и не выводит новый текст по обычному промпту.
У него два имени: Block Name — имя состояния, Block-updater Name — имя блока с командами. Имена должны отличаться.
Настраиваем inventory
Нажми + A-Block и заполни:
| Поле | Значение |
|---|---|
| Block Name | inventory |
| Block-updater Name | inventory_update |
| Char Message | Включено, если команды приходят от модели |
| User Message | Включено, если хочешь применять команды из своих сообщений |
| Inject Block | Включено, если основная модель должна видеть инвентарь |
| Hide From Display | По желанию |
Сохрани блок. Для начального состояния можно добавить в первое приветствие персонажа:
<inventory>
gold: 20
items:
- ключ
status:
location: трактир
</inventory>
После сохранения приветствия перезагрузи чат. ExtBlocks распознаёт блоки в первом сообщении и переносит их в своё хранилище. Для уже начатого чата можно добавить это состояние через Edit extblocks у сообщения или команду storage-append из раздела 19.
Как выглядит обновление
Если персонаж получил 10 монет и верёвку, источник команд должен вернуть:
<inventory_update>
$inc:
gold: 10
$push:
items: верёвка
</inventory_update>
После применения gold станет 30, а в items появится верёвка. Отсутствующие в обновлении поля сохраняются.
| Оператор | Что делает | Пример значения |
|---|---|---|
| $set | Устанавливает или заменяет значение | status.location: рынок |
| $inc | Прибавляет число; отрицательное число уменьшает | gold: -5 |
| $push | Добавляет элемент в массив; список добавляет несколько | items: фонарь |
| $pull | Убирает первый точно совпавший элемент массива | items: ключ |
| $unset | Удаляет поле | status.temporary: true |
Это поддерживаемый набор операторов в стиле MongoDB, а не полный язык запросов MongoDB. Например, $push со списком добавляет его элементы напрямую; не нужно писать $each.
Вложенные поля задаются через точку: status.location. Индекс массива тоже можно указать: quests.0.done. В $inc отправляй именно числа, а не строки в кавычках. У YAML важны отступы; используй пробелы.
Кто пишет команды обновления
Можно попросить основную модель писать <inventory_update> в своём ответе. Copy Default Prompt копирует инструкцию с операторами и примером; вставь её в промпт основного чата или в нужный G-Block. Сама кнопка не подключает инструкцию к модели и не создаёт начальное состояние.
Другой вариант — отдельный G-Block:
- Создай G-Block с именем inventory_update и шаблоном
<inventory_update>...</inventory_update>. - Добавь последние сообщения и данные о текущем инвентаре.
- В промпте попроси вернуть только фактически произошедшие изменения в YAML с $set, $inc, $push, $pull, $unset. Если изменений нет — пустой updater.
- Включи Char Message, Period 1; оставь Background Generation выключенным.
- У G-Block отключи Inject Block; Hide From Display можно включить, чтобы не показывать служебные команды.
- Назначь G-Block нужную модель. У A-Block тоже должен быть включён Char Message.
Готовый updater из обычной генерации будет обработан накопительным блоком. Если A-Block читается через Previous block, это прошлое сохранённое состояние. Для получения последнего доступного состояния можно использовать Text с {{ExtBlocks::inventory}}.
Если ты явно вызываешь G-Block командой и ему нужен A-Block, удобнее передавать состояние таким макросом в Text: ручная генерация по имени собирает список генерируемых блоков, и поиск A-Block через Previous block в таком вызове может не сработать.
Почему данные иногда удваиваются
$inc и $push повторно применяют действие. Если повторно обработать тот же updater «добавь 10 монет», можно получить ещё 10. Не проси одновременно основную модель и внешний updater применять одно и то же изменение. Для полного проверенного значения выбирай $set.
A-Block хранит последнее состояние, но не проверяет самостоятельно правильность арифметики, канон сюжета или логичность команды. Всё это нужно оговорить источнику обновлений.
17. S-Block: команды и автоматизация
S-Block выполняет STscript или JavaScript. В нём нет Template, Block Prompt и Context Builder обычного G-Block: есть текст скрипта и параметры запуска.
| Поле | Что означает |
|---|---|
| Block Name | Имя для поиска и ручного запуска |
| Script Type | STscript или JavaScript |
| Script | Код / последовательность команд |
| Triggers, Period / Keyword | Условия запуска, как у G-Block |
| Disabled | Выключение автоматической обработки |
| Execution Order | Before blocks или After blocks |
Для проверки создай STscript с именем block_notice:
/echo Блоки обработаны
Выключи автоматические события и вызови:
/extblocks-execute-script name="block_notice"
Если хочешь автоматическое уведомление, включи Char Message, Period 1 и Execution Order → After blocks. /echo показывает уведомление; это не результат G-Block в хранилище.
Скрипт может вызывать команды ExtBlocks, а также другие команды Таверны и установленных расширений. Их наличие и синтаксис проверяй через встроенную помощь и автодополнение.
JavaScript
Для Script Type → JavaScript можно использовать асинхронный код. Небольшая проверка:
const message = context.chat[messageId];
toastr.info(message?.is_user ? 'Сообщение пользователя' : 'Сообщение персонажа');
Доступны context, messageId, isUser, allBlocks, triggeredBlocks, additionalMacro, is_separate, а также сервисы и плагины расширения. Это вариант для тех, кто уже пишет код. Скрипт выполняет реальные действия в Таверне — перед импортом чужого JavaScript посмотри, что он делает.
Возвращённая JavaScript строка не становится внешним блоком автоматически. Для сохранения результата нужны соответствующие команды или BlockService.
Before blocks выполняется до Rewrite Before и обычных G-Block. After blocks — после Rewrite After. При фоновой генерации After не означает, что все фоновые запросы уже завершены.
Не вызывай из скрипта тот же скрипт по кругу и не запускай команду, которая бесконечно создаёт новое событие для него. Для ручной проверки отключи автоматические события.
18. Макросы: подставить данные или запустить действие
Макрос — запись в двойных фигурных скобках, которую Таверна заменяет значением. У ExtBlocks есть макросы чтения состояния и макросы запуска.
Прочитать последнее состояние
{{ExtBlocks::scene_info}}
То же действие имеет длинное имя:
{{ExtBlocks-GetBlockByName::scene_info}}
Подставляется последний доступный сохранённый блок с этим именем, вместе с его тегами. Конфигурация должна быть включена, открыт чат с персонажем. Если блока или состояния ещё нет, подстановка может быть пустой.
Это удобно в Text другого блока или в промпте. Если то же состояние уже передаётся через Inject Block, не дублируй его без необходимости.
Запустить по имени
| Макрос | Действие |
|---|---|
{{ExtBlocks-Call::scene_info}} |
Генерация G-Block |
{{ExtBlocks-Call::scene_info::Укажи только место}} |
Генерация с дополнительной просьбой |
{{ExtBlocks-CallRewrite::polish_text}} |
Переписывание сообщения |
{{ExtBlocks-CallScript::block_notice}} |
Выполнение скрипта |
Несколько имён указываются через запятую. Макросы запуска выполняют действие и возвращают пустую строку; это не подстановка результата вместо макроса. Для чтения результата нужен макрос состояния.
Не размещай вызов генерации в поле, которое может многократно пересобираться автоматически: повторная обработка макроса может снова вызвать запрос. Для понятного ручного запуска проще slash-команда.
Локальные подстановки
| Макрос | Что подставляет |
|---|---|
{{additionalPrompt}} |
Дополнительную просьбу из команды или окна Rewrite |
{{textToRewrite}} |
Текст, который нужно переписать |
{{mainPrompt}} |
Текущий основной Main Prompt |
{{wiBefore}} |
Активированные записи World Info перед определением персонажа |
{{wiAfter}} |
Активированные записи после определения персонажа |
{{wiExamples}} |
Активированные записи у примеров сообщений |
{{wiDepth}} |
Активированные записи с позицией по глубине |
{{wiAll}} |
Совокупность этих активированных записей |
Локальные подстановки рассчитаны на запросы G / Rewrite и их контекст. {{mainPrompt}} не добавляет весь пресет основного чата, все расширения и всю историю.
19. Все команды ExtBlocks
Команды вводятся в поле сообщения и отправляются как команды Таверны. Для запуска нужен открытый чат и существующая конфигурация с точным именем.
| Команда | Назначение |
|---|---|
/extblocks-generate name="scene_info" |
Сгенерировать названный G-Block у последнего сообщения |
/extblocks-regenerate |
Очистить блоки последнего сообщения и повторно обработать его по автоматическим условиям |
/extblocks-rewrite name="polish_text" |
Переписать последнее сообщение названным Rewrite |
/extblocks-execute-script name="block_notice" |
Выполнить названный S-Block |
/extblocks-storage-append + текст блока |
Сохранить распознанные блоки у последнего сообщения |
/extblocks-storage-purge |
Удалить всё хранилище блоков у последнего сообщения |
/extblocks-storage-export |
Добавить системную реплику с последним доступным состоянием каждого включённого блока |
/extblocks-flushinjects |
Перезагрузить текущий чат для обновления работы инъекций и отображения |
/extblocks-abort-generation |
Попытаться отменить текущий API-запрос расширения |
Несколько блоков
/extblocks-generate name="scene_info,world_news"
Дополнительная просьба
/extblocks-generate name="scene_info" Сосредоточься на месте и участниках
В промпте, шаблоне или Text должен быть {{additionalPrompt}}. Для Rewrite дополнительный текст после имени передаётся аналогично.
Отдельное сообщение
/extblocks-generate name="scene_info" is_separate=true
Этот вариант добавляет результат отдельной системной репликой в чат. По умолчанию результат сохраняется у существующего последнего сообщения. Отдельные сообщения влияют на историю и номера сообщений для Periodic.
Добавить состояние вручную
Создай и включи A-Block inventory, затем выполни:
/extblocks-storage-append <inventory>
gold: 20
items:
- ключ
</inventory>
Команда сохраняет состояние напрямую. Если таким способом добавляется updater, это не равно запуску накопления: storage-append сама по себе не применяет его операторы.
Важные особенности
Явные команды генерации, Rewrite и скриптов могут работать с выключенными конфигурациями. Автоматические триггеры при этом не включаются.
regenerate сначала удаляет старое хранилище последнего сообщения и заново проверяет условия запуска. Если нужные триггеры сейчас не подходят, блок может не появиться. Для запуска конкретного G-Block используй generate с именем. Для самого первого приветствия slash-regenerate не выполняет обычную перегенерацию.
storage-export переносит последние состояния включённых блоков, а не всю историю и не их конфигурации. Для обмена готовыми блоками используй экспорт в панели.
flushinjects не удаляет сохранённые данные блока. После перезагрузки они могут снова попасть в контекст. Чтобы прекратить передачу состояния, выключи Inject Block в конфигурации.
abort-generation не является универсальной кнопкой отмены скриптов и всех параллельных запросов. При уже полученном потоковом ответе отмена тоже может не остановить его чтение.
20. Где хранятся результаты и как их исправить
Конфигурация блока и его результаты хранятся отдельно. Конфигурация говорит, что делать; состояние у сообщения содержит то, что уже получилось.
Редактор хранилища
В дополнительных кнопках сообщения — обычно под … — найди Edit extblocks с иконкой редактирования. Откроется окно Blocks Editor.
Здесь можно исправить сохранённую сводку или YAML, добавить начальное состояние и удалить ненужный результат. Сохраняй внешние теги и правильные имена блоков. Это редактор данных конкретной реплики, а не редактор Block Prompt.
В этом окне есть Regenerate: он повторно обрабатывает выбранную реплику по условиям запуска, а не только последнее сообщение чата. Старое хранилище этой реплики сначала очищается. После ручного исправления нажми Save; Cancel отменяет правку.
Если блок уже перенесён из приветствия в хранилище, обычное редактирование текста сообщения может его не показывать. Ищи его через Edit extblocks.
Свайпы
Расширение сохраняет блоки с учётом вариантов ответа. При переключении существующих свайпов оно восстанавливает данные выбранного варианта. При генерации нового варианта блоки могут быть пересчитаны по триггерам.
После изменения старых реплик уже сохранённые сводки и состояния не становятся правильными автоматически. Проверь зависимые блоки и перегенерируй нужные результаты. Удаление и добавление сообщений также меняет расчёт Periodic.
Новый чат и перенос состояния
Новая переписка не получает историю блоков старого чата автоматически. Можно сохранить последние состояния через storage-export, скопировать нужные теги и добавить их в новый чат через редактор хранилища или storage-append. На новом месте должны существовать соответствующие конфигурации.
Начальные состояния в первом приветствии подходят для старта каждой новой истории. Для резервной копии нужны и конфигурации, и сам чат: экспорт одного G-Block не содержит прошлых результатов.
21. Лорбук, regex и оформление
World Info
Для сведений из лорбука добавь в Text, например:
Сведения мира:
{{wiAll}}
В запрос попадут активированные записи. Их активация проверяется по тексту запроса блока — его контексту, промпту и шаблону — с учётом настроек World Info. Если нужное ключевое слово не передано, запись может не активироваться.
{{wiAll}} не означает «весь лорбук независимо от ключей». Постоянные записи и правила активации продолжают иметь значение. Для небольшой обязательной справки можно использовать прямой Text.
Regex
Regex может менять отображение и содержимое, отправляемое в промпт. Блок при этом сохраняет свой исходный формат; отдельное правило превращает его в панель, таблицу или другую вёрстку.
Если автор дал JSON для ExtBlocks и JSON для Regex, импортируй каждый в свой раздел. Проверь имя в тегах, имя в правиле и области применения regex. После переименования блока старое правило может перестать срабатывать.
Настройки обработки Regex для промптов могут также менять сообщения, которые ExtBlocks собирает в контекст. Если модель блока «не видит» кусок переписки, проверь правила, которые убирают его из запросов.
HTML, CSS и изображения
HTML в Template задаёт модельный результат; фактическое отображение зависит от возможностей Таверны и правил оформления. Для сложной панели удобнее держать структуру стабильной и разрешать модели менять только данные.
Сам ExtBlocks не превращает текстовое описание в изображение. Для блока с картинкой нужна отдельная связка: генератор, внешний сервис или скрипт автора. Импорт текстового G-Block не устанавливает эту связку автоматически.
Кнопки выбора действия
У расширения есть обработчик HTML-кнопок с классом custom-menu-button. При нажатии текст из вложенного элемента custom-cyoa-option-value вставляется в поле сообщения. Он не отправляется автоматически.
<div class="custom-menu-button">
<span class="custom-cyoa-option-value">Осмотреть комнату</span>
</div>
Такая структура может использоваться в оформлении блока с вариантами действий. Чтобы она работала как кнопка, HTML должен действительно отрисоваться в чате: обычно это часть regex-оформления автора.
22. Порядок работы и связи между блоками
Когда приходит подходящее сообщение, расширение сначала применяет найденные в нём команды A-Block. Затем для сработавших G, Rewrite и S выполняется такая последовательность:
- S-Block с Before blocks.
- Rewrite с Before blocks.
- Обычные G-Block, объединённые по контексту.
- Rewrite с After blocks.
- S-Block с After blocks.
- Обработка updater-команд A-Block, полученных от обычных G-Block, завершение которых ожидалось.
Фоновые G-Block завершаются независимо от этой очереди. S-Block с After не гарантирует доступ к новым A-состояниям, обновление которых будет обработано только следующим этапом.
Для схемы «генерация → скрипт читает результат» используй обычный G-Block и макрос последнего состояния или обращение к его хранилищу. Previous block при обычной сборке контекста смотрит назад по сообщениям, а не ждёт соседний блок.
Если несколько связанных результатов нужны за один проход, можно попросить модель вернуть их в общем запросе. Если нужен отдельный второй вызов по первому результату — задай последовательность командами / скриптом и проверь, что чтение происходит после сохранения результата.
Проверяй такие связки сначала на одном блоке, затем добавляй следующий. Так легче увидеть, где теряются данные или происходит повторное обновление.
23. Возможности JavaScript для авторов блоков
Этот раздел пригодится, если ты уже используешь Script Type → JavaScript и хочешь работать с ExtBlocks из кода.
В скриптах доступны BlockService, ContextService, GenerationService, ApiService, SettingsService, MacroService, а также GeneratedPlugin, RewritePlugin, AccumulationPlugin, ScriptPlugin, PluginRegistry и состояние extStates.
| Вызов | Назначение |
|---|---|
BlockService.getAllBlocks() |
Доступные конфигурации набора и персонажа с учётом приоритета имён |
BlockService.getAllEnabledBlocks() |
Только включённые конфигурации |
BlockService.getBlocksByType(['generated'], true) |
Включённые конфигурации указанного типа |
ContextService.getPreviousBlockContextUnconditional(config, messageId, true) |
Последнее состояние, включая текущую реплику |
BlockService.addBlocksToExtra(messageId, text) |
Сохранить распознанные блоки у реплики |
BlockService.purgeBlocksExtra(messageId) |
Очистить хранилище блоков реплики |
BlockService.updateBlocksDisplay(messageId) |
Обновить показ результатов у реплики |
BlockService.injectBlock(text, config) |
Добавить содержимое в контекст по настройкам конфигурации |
BlockService.selfReloadCurrentChat() |
Перезагрузить текущий чат |
ApiService.abortGeneration() |
Отменить отслеживаемый запрос API |
executeST(command) |
Выполнить команду STscript из JavaScript |
Для программной генерации есть GenerationService.handleBlocksGeneration, для прямого вызова плагинов — методы execute. Они принимают конфигурации и параметры, включая messageId; это интерфейсы кода расширения, а не обычные поля редактора.
Прочитать состояние без изменения данных
const config = BlockService.getAllEnabledBlocks()
.find(block => block.name === 'inventory');
const state = config
? ContextService.getPreviousBlockContextUnconditional(config, messageId, true)
: '';
toastr.info(state || 'Состояние ещё не сохранено');
Запустить G-Block из JavaScript
await executeST('/extblocks-generate name="scene_info"');
Имя G-Block должно существовать. Чтобы прочитать его новый результат после вызова, выключи у него Background Generation.
Для других расширений предусмотрены события /extblocks/generate и /extblocks/generated: первое служит для вызова генерации, второе сообщает о полученном содержимом и номере сообщения. Также есть интеграция с FatPresets для импорта, смены и выключения наборов. Эти события не добавляют новые кнопки сами по себе; ими пользуется подключённое расширение или код автора.
24. Как настроить экономнее и устойчивее
Отдельное API помогает выбирать модель под задачу, но расходы зависят ещё и от контекста, частоты и длины ответа.
- Для короткой панели не передавай весь чат: начни с 6–10 последних реплик.
- Для долгой памяти передавай предыдущую сводку и новые события, а не всю историю заново.
- Включай только нужное событие запуска. User Message и Char Message вместе могут удвоить число вызовов.
- Для необязательных новостей используй ручной запуск, маркер или более редкий период.
- Не передавай визуальную панель основной модели через Inject Block, если ей эти данные не нужны.
- Не дублируй одно состояние одновременно через Inject Block, Text и Previous block без необходимости.
- Для YAML и строгих схем задай точный формат, короткую инструкцию и достаточный Max Tokens.
- Перед сложным импортом сохрани свою рабочую конфигурацию экспортом.
Слишком маленький лимит ответа может обрезать закрывающие теги и сделать результат непригодным для сохранения. Слишком большой лимит не заставляет модель писать больше, но разрешает длинный ответ.
Новости мира без внешнего поиска остаются текстом, созданным по переданным данным. Для фактических новостей сначала нужен источник свежей информации.
25. Проверка и решение проблем
Быстрая проверка G-Block
- Открой чат с персонажем.
- Проверь Enable ExtBlocks, нужный набор и отсутствие одноимённого Embedded block.
- Назначь блоку настроенную батарейку.
- Включи Char Message и Period 1, выключи Generation Pause и Background Generation.
- Добавь Last messages, сохрани Save Item → Save.
- Проверь совпадение Block Name и тегов шаблона.
- Отправь сообщение, дождись ответа и завершения внешнего запроса.
Для скачанного блока сохраняй настройки автора. Временную простую проверку удобнее делать на отдельном G-Block, а не заменять сложную связку.
Если что-то не работает
| Симптом | Что проверить |
|---|---|
| ExtBlocks вообще не появился | Установлено ли расширение, включено ли оно в управлении, обновилась ли страница |
| Панель есть, но блок не запускается | Enable ExtBlocks, Disabled, выбранный набор, событие, Period / Keyword |
| Блок работает с другой моделью | Батарейка, Connection Profile, дубли имён профилей, объединение по Item Name |
| Профиль отсутствует в ExtBlocks | Сохранён ли профиль, выбран ли Chat Completion, обновлён ли список |
| Ошибка API | Источник, модель, ключ, URL, доступ сервиса, лимит, поддержка параметров |
| Генерация прошла, но блока не видно | Hide From Display, нужные теги, незакрытый блок, данные в Edit extblocks |
| Видно текст вместо красивой панели | Установлен ли regex / CSS автора, совпадают ли имена, применимо ли правило |
| Блок путает прошлое сцены | Есть ли нужные сообщения в Context Builder, Offset, Previous block, лорбук |
| Блок скрыт, но влияет на ответы | Inject Block или подстановка того же состояния макросом |
| Блок виден, но персонаж его игнорирует | Inject Block, позиция, Main Prompt, момент генерации относительно ответа |
| Ключевое слово не срабатывает | Регистр, событие, экранирование и Regex, точный текст сообщения |
| Блок обрезан | Max Tokens, длина общего ответа группы, закрывающие теги |
| Previous block пуст | Точное имя, наличие конфигурации и прошлых сохранённых результатов |
| A-Block не меняется | Включён ли нужный триггер, совпадает ли updater_name, правильный ли YAML |
| Монеты / предметы удвоились | Повторный $inc / $push, два источника обновления одного события |
| Rewrite ничего не заменил | Есть ли <rewritten text>, подставлен ли {{textToRewrite}}, пришёл ли непустой ответ |
| Фоновой результат ещё старый | Завершился ли запрос, не прочитала ли его зависимая операция раньше времени |
| После смены набора работают странные настройки | Нет ли Embedded block с тем же именем |
Copy Debug Report
Нажми Copy Debug Report после неудачного запуска. Отчёт показывает выбранные профили, модель, API Preset, состояние расширения, сведения о последних запросах, ответах и ошибках. История отчёта ограничена; перечисление блоков тоже не является полным списком всех конфигураций.
Расширение не включает в штатные поля отчёта тексты промптов и сообщений, значения ключей и паролей. Имена профилей, моделей и адрес сервиса могут быть видны; перед публикацией посмотри, что именно скопировалось.
Для разбора проблемы полезно приложить точный текст ошибки и настройки проблемного блока. Экспорт полного промпта может содержать переписку: отправляй его только если этот текст можно показать.
