Перейти к содержанию

Плагины

Плагин — расширение, которое исполняет сам Synth. Он добавляет в платформу свои блоки системного промпта, фильтры вызовов к LLM-провайдеру и инструменты для агента.

Плагины ставит администратор инстанса. У каждого есть уровень доверия, вердикт статического сканера и запись в журнале действий.

Исполнение кода плагинов выключено по умолчанию

Установка, список, сканирование и снятие работают сразу. А вот запуск кода плагина требует отдельного включения и перезапуска инстанса — порядок в разделе «Установка и управление».

Что такое плагин

Плагин встраивается в три готовых места платформы:

Точка Что добавляет Когда применяется
promptBlocks блок системного промпта при сборке промпта, каждый ход
llmFilters фильтр вызовов к LLM перед запросом, после ответа, при эмбеддинге
tools инструмент для модели в цикле вызова инструментов, через слой прав

Плагин не заводит собственных агентов, не выбирает модель и не переписывает ролевые промпты — он добавляет только перечисленные вклады.

Плагин работает в одном из двух режимов: inline — код исполняется в процессе Synth; удалённый — в отдельном процессе, куда уходят только сериализуемые данные. В удалённом режиме плагину недоступны сервисы памяти и настроек.

Пакеты расширений и раздел «Аддоны»

Пакет расширения (synth.pack) — это контент, а не код: агенты-роли с ролевыми промптами, скиллы, MCP-серверы, пайплайны, а также правила маршрутизации и расписания, которые эти сценарии порождают. Плагин, наоборот, — код: он встраивается в три точки, описанные выше.

Пакет Плагин
Что поставляет агентов, скиллы, MCP-серверы, пайплайны, правила и расписания блоки промпта, фильтры LLM-вызовов, инструменты
Чем является контент инстанса исполняемый код
Где управляется Настройки → «Аддоны» Настройки → «Плагины»
Нужно ли подтверждение да, пакет ждёт подтверждения администратора да, при карантине после сканера

Установка пакета — одна операция, а не набор ручных шагов: сначала скиллы, затем MCP-серверы, агенты, пайплайны и правила. Новый пакет получает статус «ждёт подтверждения», и до нажатия «Подтвердить установку» в инстансе ничего не меняется — в диалоге перечислено, что именно будет добавлено.

Снятие пакета убирает и его артефакты: агентов, скиллы, MCP-серверы, пайплайны и порождённые правила маршрутизации.

Раздел Настройки → Администрирование → «Аддоны» состоит из двух частей: «Пакеты расширений» — версия, класс, статус и то, что именно поставил пакет, — и «Пайплайны» с вкладками «Определения», «Прогоны» и «Шаблоны». Шаблоны — системные заготовки, их копируют в проект как черновик. Как устроены пайплайны — Пайплайны.

Чем плагин отличается от скилла и MCP-инструмента

Плагин Скилл MCP-инструмент
Что это код, исполняемый внутри Synth текстовая инструкция для агента внешний сервис с набором инструментов
Как подключается ставится администратором, пишет файлы инстанса копируется в инстанс или приходит из реестра скиллов подключается как MCP-сервер
Что даёт блоки промпта, фильтры LLM, инструменты инструкции и вспомогательные файлы инструменты, которые агент вызывает
Где работает в процессе Synth либо в отдельном процессе (изолированный режим) не исполняется — это контент в своём процессе или сервисе
Нужен ли перезапуск да — код загружается при старте нет нет

Коротко: скилл — это инструкция, MCP-инструмент — внешний сервис, плагин — код, который работает внутри платформы.

Что плагин может и чего не может

Может:

  • добавить блок в системный промпт;
  • наблюдать вызовы к LLM-провайдеру;
  • зарегистрировать инструмент, доступный модели наравне со встроенными.

Не может:

  • обойти режимы и права (plan / act / yolo, allow / deny / ask) — инструмент плагина проходит через тот же слой прав;
  • обойти шлюз безопасности, его правила, ограничения частоты и аудит;
  • читать файлы и секреты в обход разрешений;
  • выбрать модель или подменить ролевой промпт;
  • повысить свой уровень доверия манифестом.

Модель доверия

Уровни — от старшего к младшему: builtin → verified → trusted → community.

Уровень Кто присваивает Что разрешает
builtin поставляется вместе с Synth всё, включая блокировку вызовов к LLM
verified мейнтейнер каталога расширений всё, включая блокировку вызовов к LLM
trusted оператор инстанса, каталог расширений, доверенный источник всё, включая блокировку вызовов к LLM
community обычная запись сообщества (по умолчанию) наблюдать; запрет на вызов LLM понижается до разрешения

Право блокировать вызовы к LLM есть только у доверенных плагинов. У плагина из сообщества запрещающий вердикт фильтра понижается до разрешающего, а сам факт понижения попадает в журнал.

Доверие задаёт источник установки, а не манифест: значение в манифесте — только верхняя граница.

Источник установки Откуда берётся доверие
CLI synth plugin install --trust <уровень> флаг (по умолчанию community)
Установка по HTTP уровень в запросе
Каталог расширений уровень из записи каталога — источник истины
Каталог поставки (образ или PVC) настройка plugins.deployTrust (по умолчанию trusted)

Порог доверия

plugins.trustFloor (по умолчанию trusted) — минимальный уровень для установки. Ниже порога установщик отказывает, и на диск ничего не пишется. Поэтому локальный плагин ставится с явным --trust trusted.

Сканер и решение об установке

Перед установкой бандл проходит статический скан. Код при этом не выполняется — сканер только выносит вердикт:

Вердикт Что означает Что происходит
safe подозрительных находок нет установка разрешена
caution есть находки средней тяжести бандл попадает в карантин, нужно подтверждение администратора
dangerous есть опасные находки установка отклоняется

Сканер ищет чтение секретов и переменных окружения, попытки внедрения инструкций, разрушительные операции, закрепление в системе, сетевые вызовы, обфускацию кода и невидимые Unicode-символы.

Плагин из непроверенного источника

Установка такого плагина — это запуск чужого кода на вашем инстансе. Смотрите вердикт и находки сканера до подтверждения, ставьте только то, чему доверяете, и не выдавайте плагину из сообщества права блокировать вызовы к LLM.

Внутренний режим исполнения технически даёт коду доступ к процессу Synth — это осознанный компромисс в пользу простоты. Для недоверенного кода предусмотрен изолированный режим: плагин выполняется в отдельном процессе, наружу уходят только сериализуемые данные.

Установка и управление

Сначала включите исполнение кода

Установка, список, сканирование и снятие работают сразу. Для активации (собственно запуска кода) нужны два шага:

  1. включить plugins.executionEnabled в конфигурации инстанса или в разделе «Плагины» админки;
  2. перезапустить инстанс.

Пока исполнение выключено, активация останавливается на загрузке модуля — плагин установлен, но не работает.

CLI

synth plugin list [--json]
synth plugin install <источник> [--source dir|archive|npm|url] [--version <версия>] \
                   [--sha256 <хеш>] [--trust <уровень>] [--activate] [--yes]
synth plugin update <имя> [--version <версия>] [--sha256 <хеш>] [--activate] [--yes]
synth plugin rollback <имя>
synth plugin approve <имя> [--version <версия>] [--activate] [--yes]
synth plugin enable <имя>
synth plugin disable <имя>
synth plugin remove <имя> [--keep-files] [--yes]
synth plugin scan <путь> [--json]

Источник установки — каталог с бандлом, архив .tgz / .tar.gz, npm-пакет или ссылка https:// на архив. Для ссылки обязателен pin --sha256 (64 hex-символа): произвольный адрес без контрольной суммы не ставится. Для npm-источника требуется integrity-хеш из метаданных пакета.

Обновление берёт источник из записи об установке, а не из аргументов: npm-пакет — по имени и версии, архив — по сохранённому пути, ссылка — по адресу с новым обязательным хешем. Откат возвращает предыдущую версию (одна ступень, откат обратим).

CLI правит файлы инстанса, а не живой процесс

Команды CLI — офлайн-операции: они записывают файлы инстанса и реестр установленного, но не переключают работающий сервер. Изменения вступают в силу после перезапуска. Управление живым инстансом — через админку и HTTP API.

Админка

Раздел «Плагины» в настройках (доступен администратору) состоит из трёх частей:

  • «Установленные плагины» — версия, режим исполнения, уровень доверия, вердикт сканера и контрольная сумма бандла; там же включение и выключение, подтверждение карантина, обновление, откат и снятие;
  • «Журнал плагинов» — последние записи журнала действий: время, плагин, действие, итог и причина отказа; кнопка «Обновить»;
  • «Политика слоя» — мастер-выключатель слоя, исполнение кода, установка во время работы, порог доверия, сканирование, бюджет блока промпта и таймаут фильтра LLM-вызовов.

Политика слоя применяется после перезапуска инстанса.

Журнал действий

Каждое действие слоя фиксируется: установка и подтверждение, включение и выключение, обновление и откат, снятие, срабатывания фильтров и причины отказов — включая понижение запрета до разрешения у плагина из сообщества.

Смотреть: блок «Журнал плагинов» в разделе «Плагины» (кнопка «Обновить»), по API — GET /api/v2/plugins/audit с фильтрами limit и plugin. Записи видит администратор; в локальном режиме — владелец инстанса.

HTTP API

Сценарий Запрос
Список установленных GET /api/v2/plugins
Журнал действий плагинов GET /api/v2/plugins/audit (limit, plugin)
Карточка плагина: манифест и состояние целостности GET /api/v2/plugins/:name
Установка POST /api/v2/plugins/install
Подтверждение карантина POST /api/v2/plugins/:name/approve
Включение и выключение POST /api/v2/plugins/:name/enable и .../disable
Обновление из источника записи POST /api/v2/plugins/update
Откат на предыдущую версию POST /api/v2/plugins/:name/rollback
Снятие DELETE /api/v2/plugins/:name
Настройки слоя GET/PUT/DELETE /api/v2/settings/plugins

Права: в серверном режиме чтение и настройки — администратору; установка, включение, выключение, обновление и откат доступны также машинному ключу с правом на установку расширений; подтверждение карантина и снятие — только администратору. В локальном (standalone) режиме эти права есть у владельца инстанса. Установка во время работы инстанса по умолчанию запрещена и включается отдельной настройкой.

Где это хранится

  • установленные бандлы — в каталоге плагинов инстанса;
  • ожидающие подтверждения — в карантине;
  • реестр установленного (что установлено, из какого источника, какая версия) — в файле plugins.lock.json;
  • журнал действий — блок «Журнал плагинов» в разделе «Плагины» админки; файл журнала — audit/plugins.jsonl в каталоге данных инстанса.

Поставка образом или каталогом

Плагин, положенный в каталог поставки (plugins.deployDir), ставится при старте инстанса и помечается как управляемый: снять или обновить его через CLI и API нельзя — меняется только новый образ или переразвёртывание каталога. Так удобно в закрытом контуре, где состав расширений фиксирован.

Проверка плагина

Убедиться, что плагин работает, помогают три признака:

  1. Блок в промпте. Отправьте в сессию сообщение, которое должно вызвать блок, и посмотрите состав промпта: там должна появиться запись блока с признаком происхождения от плагина.
  2. Инструмент доступен. Попросите агента вызвать инструмент плагина. Полное имя инструмента собирается из имени плагина и имени инструмента, поэтому в ответе агента видно, что вызов ушёл в расширение.
  3. Фильтр срабатывает. Если у плагина есть фильтр, подставьте в запрос то, что он должен отклонить (например, тестовый секрет). Доверенный плагин остановит вызов; для плагина из сообщества это сработает как наблюдение, а не как блокировка.

Где смотреть:

  • Настройки → Плагины — статус, вердикт скана, активность;
  • журнал плагинов — блок «Журнал плагинов» в том же разделе «Плагины»: установки, активации, срабатывания фильтров и причины отказов; то же отдаёт GET /api/v2/plugins/audit, файл журнала — audit/plugins.jsonl;
  • состав промпта сессии — блоки от плагинов;
  • журнал шлюза безопасности — решения фильтров, включая понижение запрета до разрешения у недоверенного плагина.

Гибридный режим

В гибридном режиме локальный контур и сервер — два разных мира, и оператор сервера может ограничивать список плагинов, которым разрешено работать на клиенте. По умолчанию ограничение не задано: плагин работает локально как обычно, но получает пометку «не проверен сервером». Если ограничение задано, плагин вне списка установить можно, а активировать — нет. Проверка идёт по имени плагина и касается именно активации.

Для обращения плагина к серверу оператор выдаёт ему привязанный ключ с ограниченным набором прав и сроком жизни. Такой ключ сервер принимает только в запросах, где явно указано имя плагина, к которому он относится, поэтому его нельзя переиспользовать от имени другого плагина, а серверную политику сервер применяет сам.

Подробнее о гибридном режиме — Гибридный режим.

Публикация своего плагина

Состав бандла

my-plugin/
├── synth.pack          # манифест расширения
├── package.json        # нужен только для сборки
├── src/index.ts        # исходник
└── dist/index.js       # собранный ESM-бандл (его грузит Synth)

Плагин распространяется как самодостаточный ESM-бандл: всё нужное в рантайме вшито в файлы бандла, установка npm-зависимостей не выполняется.

Манифест

{
  "name": "my-plugin",
  "version": "0.1.0",
  "kind": "plugin",
  "description": "Что делает плагин",
  "host": ">=0.11.0 <0.13.0",
  "contracts": { "extensionApi": "^1" },
  "mode": "inline",
  "provides": {
    "tools": ["notes_search"],
    "promptBlocks": [
      {
        "key": "plugin.my-plugin.notes",
        "tier": "context",
        "order": 120,
        "title": "Заметки проекта"
      }
    ],
    "llmFilters": [
      {
        "id": "plugin:my-plugin:dlp",
        "phase": "pre_request",
        "failMode": "closed",
        "timeoutMs": 200
      }
    ]
  },
  "permissions": { "network": [], "secrets": [], "tools": [], "hooks": [] },
  "trust": { "level": "community", "source": "local" }
}

Обязательны name, version, kind, description и хотя бы один вклад в provides. host и contracts задавать стоит обязательно: без них проверка совместимости не работает и плагин может «тихо» активироваться на несовместимой версии Synth.

Объявленное в provides должно совпадать с тем, что плагин реально регистрирует: хост сверяет списки поимённо и отказывает в активации при расхождении — так ловится несогласованная сборка.

Точка входа

import type { LlmCallFilter, PromptBlockProvider } from '@itphx/synth-shared';
import type { PluginFacade } from '@itphx/synth-core';

const block: PromptBlockProvider = {
  key: 'plugin.my-plugin.notes',
  tier: 'context',
  order: 120,
  title: 'Заметки проекта',
  load(ctx) {
    return ctx.query ? `Вопрос: ${ctx.query}` : null;
  },
};

const filter: LlmCallFilter = {
  id: 'plugin:my-plugin:dlp',
  phase: 'pre_request',
  failMode: 'closed',
  timeoutMs: 200,
  inspect(input) {
    const text = input.systemPrompt ?? '';
    return /-----BEGIN [A-Z ]*PRIVATE KEY-----/.test(text)
      ? { verdict: 'deny', code: 'private_key', reason: 'в запросе приватный ключ' }
      : { verdict: 'allow' };
  },
};

export function apply(facade: PluginFacade): void {
  facade.registerPromptBlock(block);
  facade.registerLlmFilter(filter);
  facade.registerTool(tool); // инструмент объявляется в provides.tools
}

Точка входа — файл .js или .mjs внутри каталога бандла, до 8 МиБ. Модуль обязан отдать функцию apply (допустимы также export default { apply } и export default function apply). Импорты @itphx/* — только для типов: они стираются при сборке, и в бандле не остаётся обращений к пакетам хоста.

Сборка, например:

npx esbuild src/index.ts --bundle --format=esm --platform=node --target=node20 \
  --outfile=dist/index.js

Проверка перед публикацией

  • synth plugin scan ./my-plugin — вердикт и находки сканера;
  • установка на тестовом инстансе и проверка трёх признаков из раздела «Проверка плагина»;
  • журнал плагинов — без неожиданных отказов.

Каталог расширений

Плагин публикуется в общем каталоге расширений: запись — отдельный файл entries/<владелец>__<репозиторий>.yml в репозитории каталога gitverse.ru/itphx/synth-registry по готовому шаблону.

Поле Значение
kind plugin
name совпадает с именем в манифесте
version совпадает с версией в манифесте
trust_level честный уровень доверия — именно он определяет доверие при установке из каталога
identifier <владелец>/<репозиторий>
install.command команда установки; для плагина по умолчанию — synth plugin install <имя>

Описание записи — в обеих локалях, лицензия обязательна, а версия в записи и в манифесте должны совпадать: иначе пользователь увидит на витрине один номер версии, а в списке плагинов — другой.

Диагностика

Симптом Причина Что делать
Плагин установлен, но ничего не делает не включено исполнение кода или нужен перезапуск включите plugins.executionEnabled и перезапустите инстанс
Установка отклонена с требованием доверия уровень ниже порога инстанца поставьте с --trust trusted или попросите оператора выдать нужный уровень
Плагин в карантине сканер просит подтверждения посмотрите находки (synth plugin scan) и подтвердите установку
Установка отклонена сканером опасные находки устраните их (чтение секретов, запуск внешних процессов, исполняемые бинарники) и пересоберите бандл
Инструмент не появился у модели плагин не активирован, регистрация отклонена, либо инструмент недоступен в текущем режиме сессии проверьте статус плагина, набор прав инструмента и режим сессии; в режиме плана мутирующие права закрыты
Активация отклонена из-за несовпадения объявленного и фактического расхождение между provides и кодом синхронизируйте манифест и код, пересоберите бандл
Блок промпта не виден блок не сработал на этот вопрос, был обрезан по бюджету или у сессии задан свой системный промпт посмотрите состав промпта и журнал плагинов
Фильтр не заблокировал вызов у плагина нет права вето (уровень ниже доверенного) или выключен шлюз безопасности получите доверие у источника; проверьте, что шлюз включён
Плагин не снимается плагин управляемый (поставлен образом или каталогом) меняйте версию новым образом или переразвёртыванием каталога
После изменения ничего не изменилось CLI правит файлы, а живой процесс работает со старой версией перезапустите инстанс

Что дальше