dsh-agent-tool-filter
English version: see README.en.md.
Per-agent фильтр инструментов основного агента (ведущего задачу) для DeepSeek Harness.
Цель — независимые наборы tools: выбранные пресеты работают с обрезанным набором
(экономия на tool-схемах в каждом запросе), субагенты сохраняют полный набор,
включая web. Штатного per-agent фильтра для основного агента в DSH нет.
Обзор
Плагин сопоставляет выбранные пресеты агентов с профилями фильтрации, сокращая набор
tool-схем, видимых основному агенту. Ограничения применяются в scope самого агента;
субагенты сохраняют полный набор инструментов, включая web-инструменты.
Фильтрация включается только через сопоставление пресетов. Плагин не изменяет
существующие пресеты, пока они явно не связаны с профилем в его конфигурации.
Важно перед установкой
- Возможности плагина могут пересечься с обновлениями DSH. Функциональность
per-agent фильтрации со временем может быть встроена в саму платформу. Прежде чем
устанавливать плагин, проверьте актуальную версию DSH и список её обновлений:
если нужные возможности уже доступны штатно, отдельный плагин не требуется.
- Фильтрация действует только на основного агента. Скрытые инструменты у него
отключаются; у субагентов они остаются доступными — плагин не переносит
ограничения автоматически. Чтобы ограничение стало сквозным:
- настройте для каждого субагента собственный пресет с подходящим набором
инструментов. Например, для веб-поиска оставьте субагенту только web-инструменты
и
read; для других сценариев выберите свои наборы;
- пропишите основному агенту рабочие сценарии: когда задача требует скрытого
инструмента — не пытаться вызвать его напрямую, а передать задачу
субагенту, у которого этот инструмент доступен.
Без этих настроек агент будет упираться в отключённые инструменты вместо
делегирования — фильтрация сработает, но рабочий процесс сломается.
Ограничение набора инструментов через пресет не подходит для этой задачи: оно
фиксируется при создании чата и наследуется субагентами, ограничивая их вместе
с основным агентом. Маска плагина применяется только к основному агенту и может
меняться без этих ограничений.
Возможности
- Сопоставление пресетов агентов с именованными профилями фильтрации (UI-карточка с матрицей «пресет → профиль»).
- Ограничения применяются через
tools.restrict() в scope корневого агента.
- In-process дочерние агенты и SDK-субагенты не затрагиваются.
- Один встроенный профиль (
balanced) плюс импортируемые пакеты-шаблоны; пользовательские профили с копированием и правкой в модальных окнах.
- Копирование пресетов вместе с их описаниями (встроенные берут display-тексты DSH, кастомные сохраняют свои метаданные).
- Сканирование установленной палитры инструментов (сводка «можно отключить / нельзя отключить») с предупреждениями и причинами.
- Русский и английский интерфейс (переключатель языка, режим «Как в приложении»).
- Расширенные права субагентов (с 1.1.0): необязательный тумблер
subagentEscalation (по умолчанию выкл) даёт субагенту запросить расширенный доступ, когда ему не хватает инструмента для задачи. Каждое повышение прав требует явного одобрения пользователя в панели над блоком ввода, которая раскрывает действие до выдачи разрешения: кто запрашивает (пресет и задание субагента), обоснование, операция (инструмент) и точные аргументы вызова. Разрешение действует ровно на один вызов («Разрешить один раз»); отклонение — кнопкой или Esc. Параллельные запросы копятся в очереди до решения пользователя, каждый со своей идентификацией; ошибки механизма разрешение не выдаётся (fail-closed), прерванный субагент снимает свой запрос из очереди. Функция независима от фильтрации tools: работают режимы «только ограничение tools», «только расширенные права» и «обе функции».
- Блок диагностики с техническими данными (remote, locale, версия, счётчики).
- Файловая диагностика: тумблер
debugLog в настройках плагина (по умолчанию выкл, переключение применяется сразу). Лог пишется в <DSH_HOME>/logs/agent-tool-filter-debug.log; ATF_DEBUG_LOG=<путь> принудительно включает запись лога с собственным путём файла.
Технологии
- Платформа: плагин хоста DeepSeek Harness.
- Зависимости: отсутствуют; пакеты
@deepseek-ai/* предоставляет хост.
Требования
- Установленный DeepSeek Harness с доступом к Plugin Manager для установки bundle.
- Пакет предоставляет дефолтную строку bundle; сопоставление пресетов и профили настраиваются в его UI-карточке.
Механика
- На событии
agent/created (listeners отрабатывают до первой сборки prompt) плагин
определяет пресет агента (agentPresets.composedPreset(agent.ctx)) и по
конфиг-матрице «пресет → профиль» выбирает профиль фильтрации.
- Ограничение ставится в scope самого агента:
agent.ctx.tools.restrict(...).
Фильтруются только корневые агенты: in-process субагенты присоединяются к пресету
родителя (composeFrom) и показывают тот же пресет — без проверки roots() фильтр
задел бы субагентов. SDK-субагенты живут в отдельном процессе и не задеваются вовсе.
- Маски
restrict() пересекаются, поэтому при смене конфига старые ограничения
снимаются (disposers), а новые ставятся заново. Состояние хранится на самом агенте
и переживает hot-reload плагина.
- Собственные registrations scope (own-layer и динамические:
team_*, team_task_*,
spawn_teammate, wait_agent, structured-output и пр.) restrict() не маскирует.
Расширенные права субагентов (с 1.1.0)
Фильтрация ограничивает основного агента, а субагенты работают со своим набором
инструментов. Если субагенту не хватает инструмента для задачи, тумблер «Расширенные
права субагентов» (subagentEscalation, по умолчанию выкл) даёт ему путь запросить
расширенный доступ у пользователя:
- каждое повышение прав требует явного одобрения — панель появляется над блоком ввода
в чате и раскрывает действие до выдачи разрешения: кто запрашивает (пресет и задание
субагента), обоснование, операцию (инструмент) и аргументы вызова; панель и кнопки
следуют языку UI плагина (русский или английский);
- разрешение действует ровно на один вызов («Разрешить один раз»); отклонение — кнопкой
или Esc;
- несколько параллельных запросов копятся в очереди до решения пользователя, каждый со
своей идентификацией; при ошибках механизма разрешение не выдаётся (fail-closed);
прерванный субагент снимает свой запрос из очереди;
- функция независима от фильтрации tools: работают режимы «только ограничение tools»,
«только расширенные права» и «обе функции».
По умолчанию тумблер выключен — субагенты работают без эскалации.
Конфигурация
Пакет устанавливается как bundle через Plugin Manager и сам предоставляет строку плагина.
Настройте матрицу и профили в UI-карточке; изменения применяются горячо (HMR). Ниже — пример
значений конфигурации:
- insert:
- id: agent-tool-filter
name: dsh-agent-tool-filter
config:
enabled: true
behavior: auto # auto выбирает hide/block по истории; hide или block фиксируют режим
debugLog: false # файловая диагностика шагов фильтрации
language: auto # язык UI плагина: auto/ru/en
subagentEscalation: false # право субагентов запрашивать расширенный доступ с одобрением пользователя
presets: # матрица «id пресета → имя профиля»; пусто = не фильтровать нигде
cordis: cordis-trim
standard: minimal-orchestrator
profiles: # свои профили и правка дефолтных (переопределяют по имени)
my-profile:
mode: deny # deny — убрать перечисленные; allow — оставить только их
tools: [web_search, web_fetch]
| Поле | Дефолт | Значение |
|---|
enabled | true | false — плагин пассивен |
behavior | auto | режим совместимости: auto выбирает по истории, hide скрывает схемы (см. сноску о рисках), block оставляет схемы видимыми, но блокирует выбранные вызовы |
debugLog | false | файловая диагностика шагов фильтрации (путь файла — в блоке «Диагностика») |
presets | пусто | матрица «пресет → профиль»; пусто = ничего не фильтровать (установка не меняет поведение пресетов) |
profiles | встроенные (см. ниже) | пользовательские профили; совпадение имени перекрывает встроенный |
language | auto | язык UI плагина: auto — как в приложении, либо ru / en |
subagentEscalation | false | true — включает право субагентов запрашивать расширенный доступ с обязательным одобрением пользователя; false — субагенты работают без эскалации |
⚠ Риск режима hide: фиксированное скрытие схем не защищает от ошибок строгих
провайдеров — если в истории чата остались вызовы скрываемых инструментов, ходы могут
завершаться ошибкой «Провайдер вернул некорректный вызов инструмента». Режим auto
сам выбирает безопасное поведение по истории; фиксируйте hide только когда история
чиста либо провайдер мягкий.
Профили фильтрации и шаблоны
По умолчанию установлен один универсальный профиль; остальные добавляются импортом
пакетов-шаблонов прямо из UI-карточки.
| Профиль/пакет | Содержимое (deny) | Идея |
|---|
balanced (встроенный) | админ: plugin_manager, security_audit, test_drive, drive_report, create_skill, subagent_fork | базовая обрезка для любого пресета |
пакет gradient | strict (админ + web), soft (web) | ступени ограничения вокруг balanced |
пакет roles | focus, no-web, no-admin, minimal | профили по назначению |
пакет layers | no-web, no-admin, no-dev-skills | одна категория = один профиль, комбинируйте копиями |
Любой профиль можно скопировать и править под себя (свои списки tools, режим
deny/allow); встроенный balanced переопределяется по имени, но не удаляется.
Что делает установка
Пакет не добавляет пресетов, инструментов и чужой конфигурации — только файлы плагина и bundle-строку с безопасной конфигурацией по умолчанию. При первой активации плагин сканирует установленный DSH (реальные tools и
пресеты) и сверяет профили обрезки с вашим набором; отчёт — в лог. Фильтрация выключена до
тех пор, пока вы не свяжете пресет с профилем (матрица presets). Подробная инструкция —
docs/filtering-guide.md.
UI
UI-карточка настроек открывается из Plugin Manager: строка dsh-agent-tool-filter →
Configure. В карточке:
- тумблер «Фильтрация включена» и статус (агенты с маской, скрыто схем);
- тумблер «Файловая диагностика» — вкл/выкл запись лога шагов фильтрации; путь файла
показан в блоке «Диагностика»;
- тумблер «Расширенные права субагентов» — эскалация прав субагентов через одобрение
пользователя (с 1.1.0);
- матрица «пресет → профиль» карточками в два блока (дефолтные и кастомные):
связка/замена/снятие профиля, копия пресета (с предпросмотром описания) и
удаление кастомных;
- профили: создание/правка/копия в модальных окнах, три группы tools (включённые,
управляемые, неуправляемые), импорт пакетов-шаблонов; проблемные имена (опечатки,
«ограничитель отклонит маску») показываются с активным чекбоксом и пометкой —
снятие отметки и сохранение убирает имя из профиля;
- сканирование tools — сводка по палитре DSH («✅ N tools можно отключить /
⚠ M tools нельзя отключить») и предупреждения с причинами; у предупреждений
«не найдено» — кнопка «Убрать имя из профиля» (имя исчезает из всех профилей);
- диагностика — свёрнутый блок с техническими данными (remote, locale, версия,
путь файла лога, счётчики);
- интерфейс на русском и английском (переключатель языка, режим «Как в приложении»); в Plugin Manager также доступны русские и английские метаданные и оригинальная иконка плагина.
Валидация имён и диагностика
- При старте и по
scanTools() плагин сверяет имена инструментов в профилях с глобальным
списком tools. Неизвестные и нефильтруемые имена (own-layer registrations: team_task_*,
spawn_teammate, wait_agent) попадают в предупреждения (лог и UI-карточка), а не в
тихий пропуск.
restrict() дополнительно проверяет имена при применении: неизвестное имя не блокирует
остальные (deny применяется поимённо), ошибка попадает в лог с перечнем пропущенных.
- Диагностика: «сколько схем скрыто текущим фильтром» — в логе (строка применения) и в
agentToolFilter.status().agents[].hidden.
- Файловая диагностика: тумблер
debugLog в настройках плагина (по умолчанию выкл, переключение применяется сразу). Лог пишется в <DSH_HOME>/logs/agent-tool-filter-debug.log; ATF_DEBUG_LOG=<путь> — принудительное включение с собственным путём файла.
Совместимость с провайдерами
Режим работы плагин выбирает автоматически — отдельных настроек для этого нет.
- Строгие провайдеры сверяют вызовы инструментов из истории диалога
с текущим списком tools: если схема инструмента скрыта, а в истории есть его вызовы,
запрос завершается ошибкой провайдера («Провайдер вернул некорректный вызов
инструмента»). Мягкие провайдеры такую историю принимают.
- Если история агента уже содержит вызовы скрываемых инструментов, плагин временно не
скрывает схемы, а вызовы скрываемых инструментов блокирует с подсказкой делегировать
задачу субагенту — так история и список инструментов не расходятся ни у строгих, ни у
мягких провайдеров.
- После сжатия истории чат переходит на обычное скрытие схем — экономия
контекста включается автоматически (проверено: после сжатия скрытые схемы исчезают
из запроса модели).
- Если скрываемые инструменты в чате никогда не вызывались — скрытие схем включается
сразу, даже в старом чате (проверено: чат работает без ошибок).
Особенности работы в web-среде (с 1.0.1)
- Новые чаты: фильтр стабилен — маска применяется при создании агента, hide-режим (обрезка схем) виден с первого хода.
- Старые чаты с «грязной» историей (есть вызовы скрываемых инструментов): авто-режим держит guard — схемы остаются в списке, вызовы скрываемых блокируются. Это защита от ошибки «Провайдер вернул некорректный вызов инструмента» на строгих провайдерах.
- Смена guard → hide происходит при пере-оценке режима: после компакции (с 1.0.1), при смене пресета агента или перезапуске DSH. Если summary компакции упоминает скрытые имена — режим осознанно остаётся guard (консервативная защита), hide придёт, когда история перестанет их упоминать.
- Диагностика наблюдений: тумблер
debugLog в настройках плагина или переменная ATF_DEBUG_LOG.
Обратимость (памятка)
- Выключение (
enabled: false) и правки конфига действуют на новых агентов
(создание/resume/clear). Для живого сеанса надёжный путь — перезапуск DSH или
пересоздание агента (clear/resume): scope агента пересоздаётся, фильтр применяется заново.
- Плагин дополнительно пытается применить изменения к живым агентам сразу
(hot-apply при
app-boot/config-reload), но полагаться на это как на единственный путь
не стоит.
- Снятие фильтра у конкретного агента без перезапуска: удалить пресет из матрицы
presets
и пересоздать агента; ограничения снимаются со scope агента автоматически при dispose.
restrict() — ограничение видимости для модели (и экономия на схемах), НЕ sandbox и
не гарантия безопасности.
Установка
В Plugin Manager установите пакет через plugin_manager → install_bundle, указав путь
к релизному .tgz или к каталогу распакованного пакета. Для npm-пакета сначала получите
его в доступном окружению каталоге, затем передайте путь к каталогу пакета в install_bundle.
Менеджер установит и подключит bundle; вручную править профильный cordis.patch.yml или
распаковывать пакет в профиль не нужно. Первую активацию при необходимости завершите
перезапуском DSH. Зависимостей у пакета нет; модули @deepseek-ai/* предоставляет хост.
Структура репозитория
| Каталог / файл | Назначение |
|---|
cordis.patch.yml | Bundle-патч со строкой плагина и безопасными дефолтами |
lib/, client/, plugin.mjs | Исходники плагина (host и client) |
locale/ | Локализации интерфейса (RU/EN) |
scripts/ | Сборка клиентского бандла (build.mjs) |
docs/ | Руководства по фильтрации (RU/EN) |
test/ | Тестовые модули (*.test.mjs) и отчёт о тестировании |
README.md / README.en.md | Русская / английская документация проекта |
CONTRIBUTING.md / CONTRIBUTING.en.md | Руководство для контрибьюторов (RU/EN) |
LICENSE / LICENSE.en | Лицензия MIT (RU / EN) |
SECURITY.md / SECURITY.en.md | Политика безопасности (RU / EN) |
Версии и релизы
Номера версий и заметки к релизам публикуются в
GitHub Releases репозитория.
Внесение вклада
Руководство — в CONTRIBUTING.md (RU) и
CONTRIBUTING.en.md (EN). Перед вкладом проверьте синтаксис
изменённых файлов (node --check) и тесты: node --test test/.
Безопасность
Политика безопасности — в SECURITY.md (EN: SECURITY.en.md).
Лицензия
MIT — см. LICENSE. Copyright (c) 2026 Kiol.
Контакты