Skip to Content
ДизайнДизайн required capabilities для skill

Дизайн required capabilities для skill

Статус: заметка к дизайну; этот PR реализует Вариант B и оставляет required-capabilities как предложение на будущее.

Контекст

Web Shell может рендерить кастомные fenced code blocks через свой markdown-рендерер. Предложение по рендереру графиков использует fenced code block echarts-fulldata, чтобы модель могла возвращать полные опции ECharts и полезные данные dataset, которые Web Shell отрендерит как интерактивный график.

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

Изначальное предложение по встроенному skill для графиков полагалось на формулировки, чтобы сообщить модели, что формат предназначен для Web Shell. Это мягкое ограничение. Если skill доступен в сессии не Web Shell, модель всё равно может выбрать формат вывода, который клиент не сможет отрендерить.

В текущем PR Qwen Code сохраняет точку расширения рендерера в Web Shell, но не включает qwencode-viz в ядро. Пакет Web Shell включает копируемый, не загружаемый автоматически шаблон skill, и хосты должны устанавливать или внедрять этот skill только тогда, когда они также регистрируют рендерер echarts-fulldata.

Проблема

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

Для qwencode-viz конкретный вопрос звучит так:

  • Должно ли ядро поддерживать универсальное поле метаданных skill required-capabilities?
  • Или qwencode-viz вообще не должен быть встроенным skill в ядре, а предоставляться только клиентами Web Shell, которые устанавливают или внедряют его?

Цели

  • Предотвратить доступность специфичных для рендерера skills, когда текущий клиент не может удовлетворить их контракт вывода.
  • Сохранить согласованность напоминаний о skills при запуске, явной активации skills, обнаружения slash-команд и валидации skills.
  • Избегать хардкода qwencode-viz как особого случая.
  • Сохранить существующее поведение skill, когда не объявлено требований к возможностям (capabilities).
  • Сохранить расширяемость дизайна для будущих возможностей хоста, не только ECharts.

Не цели

  • Реализация самого рендерера ECharts.
  • Перепроектирование всего согласования возможностей клиент/сервер.
  • Изменение семантики существующего frontmatter для skill.
  • Решение изменений возможностей в общих сессиях с несколькими клиентами в первой версии.

Текущие связанные механизмы

В кодовой базе уже есть несколько механизмов управления видимостью, но ни один не представляет возможности рендеринга клиента:

  • disable-model-invocation: предотвращает автоматический вызов skill моделью.
  • user-invocable: управляет доступностью встроенного skill в качестве команды.
  • paths: ограничивает доступность skill соответствующими путями рабочего пространства.
  • skills.disabled: отключает настроенные skills.
  • allowedTools: в настоящее время используется загрузкой встроенных skills для скрытия skills, ориентированных на cron, когда инструменты cron недоступны.
  • supportedModes для slash-команд: фильтрует команды по режиму выполнения.
  • Объекты возможностей Daemon и ACP: описывают поддержку протокола или клиента, но в настоящее время не связаны с доступностью skills.

Не существует текущего required-capabilities или эквивалентного frontmatter для skill. Его добавление станет новым контрактом skill.

Вариант A: Добавить required-capabilities

Добавить универсальное поле frontmatter для skill:

--- name: qwencode-viz description: Рендеринг аналитических графиков в Web Shell с использованием fenced code blocks echarts-fulldata. required-capabilities: - markdown.codeBlock.echarts-fulldata ---

Когда текущий клиент/сессия не анонсирует все перечисленные возможности, skill считается недоступным.

Именование возможностей

Использовать возможности в виде строк с пространством имен:

markdown.codeBlock.echarts-fulldata

Это сохраняет универсальность поля, делая контракт точным:

  • markdown: возможность относится к отрендеренному markdown.
  • codeBlock: возможность применяется к рендерингу fenced code blocks.
  • echarts-fulldata: конкретная строка языка/информации, поддерживаемая рендерером.

Примеры в будущем могут включать:

  • markdown.codeBlock.vega-lite
  • markdown.codeBlock.mermaid-interactive
  • artifact.openUrl

Метаданные skill

Добавить requiredCapabilities?: string[] в конфигурацию skill после парсинга ключа frontmatter required-capabilities.

Оба пути парсинга skill должны понимать это поле:

  • packages/core/src/skills/skill-load.ts
  • packages/core/src/skills/skill-manager.ts

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

Источник возможностей в runtime

Добавить возможности клиента/сессии в конфигурацию runtime:

interface ConfigParameters { clientCapabilitiesProvider?: () => ReadonlySet<string>; }

Предоставить хелпер в Config, например:

config.getClientCapabilities(): ReadonlySet<string>

Затем централизовать проверку:

function skillMeetsRequiredCapabilities(skill: Skill, config: Config): boolean { return skill.config.requiredCapabilities.every((capability) => config.getClientCapabilities().has(capability), ); }

Точки фильтрации

Фильтр возможностей должен применяться до того, как skills станут доступны модели или пользователю:

  • collectAvailableSkillEntries в packages/core/src/tools/skill-utils.ts должен пропускать skills, у которых отсутствуют требуемые возможности. Это обеспечит согласованность напоминаний о skills при запуске, delta-напоминаний, валидации SkillTool и активации, вызываемой моделью.
  • BundledSkillLoader должен пропускать недоступные встроенные skills при создании команд для пользователя.
  • SkillCommandLoader должен пропускать недоступные skills файловой системы при создании команд для пользователя.

Важный инвариант заключается в том, что skill, скрытый от модели, не должен отображаться как вызываемая команда, если только проект намеренно не поддерживает ручное переопределение.

Регистрация в Web Shell

Web Shell должен явно анонсировать поддержку рендерера, а не полагаться на наличие непрозрачного колбэка renderCodeBlock.

Например:

<WebShell customization={{ markdown: { renderableCodeBlockLanguages: ['echarts-fulldata'], renderCodeBlock(info) { // render custom blocks }, }, }} />

Клиент Web Shell может сопоставить это с:

markdown.codeBlock.echarts-fulldata

Это делает объявление возможности стабильным, даже если колбэк рендерера содержит кастомную логику, фолбэки или несколько поддерживаемых языков.

Передача в Daemon и ACP

Для хостинговых или daemon-сессий набор возможностей клиента должен достигать ядра до загрузки или вывода списка skills. Минимальная версия может передавать возможности при создании сессии:

interface CreateSessionRequest { clientCapabilities?: string[]; }

Daemon bridge, SDK и поток создания сессии ACP могут хранить это как конфигурацию с областью действия сессии (session-scoped config).

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

Плюсы

  • Сохраняет qwencode-viz как единый канонический встроенный skill.
  • Предотвращает утечку специфичных для хоста контрактов вывода в неподдерживаемые клиенты.
  • Создает переиспользуемый механизм для будущих специфичных для рендерера или хоста skills.
  • Делает зависимость явной и тестируемой.

Минусы

  • Добавляет новое сквозное поле метаданных skill.
  • Требует передачи возможностей клиента/сессии через интерфейсы Web Shell, daemon, SDK и ACP.
  • Требует тщательного документирования поведения общих сессий.
  • Может оказаться избыточным механизмом, если qwencode-viz — единственный ожидаемый skill, зависящий от возможностей.

Вариант B: Skill, предоставляемый клиентом

Не добавлять универсальное поле required-capabilities. Вместо этого не включать qwencode-viz в ядро. Клиент Web Shell или любой другой клиент, поддерживающий рендерер, предоставляет сам skill.

Возможные модели распространения:

  • Хост Web Shell устанавливает .qwen/skills/qwencode-viz/SKILL.md.
  • Пакет Web Shell поставляется с опциональным, не загружаемым автоматически шаблоном skill, который хост может скопировать или установить при включенном рендеринге графиков.
  • Интеграция Web Shell поставляется с пакетом расширения skill.
  • Интеграция Web Shell внедряет эквивалентные инструкции для модели только тогда, когда включен её рендерер графиков.

В этой модели skill доступен только потому, что клиент с рендерером решил его предоставить.

Плюсы

  • Минимальные изменения в ядре.
  • Нет нового глобального контракта метаданных skill.
  • Доступность возможностей естественным образом принадлежит клиенту, который реализует рендерер.
  • Избегает передачи через daemon или ACP, если только у клиента уже нет механизма внедрения skills.

Минусы

  • Нет канонического встроенного skill, если только все клиенты не копируют один и тот же контент.
  • Большая нагрузка на каждого интегратора Web Shell.
  • Пользователи, переходящие между клиентами, могут столкнуться с несогласованной доступностью skills.
  • Не создает общей защиты для будущих специфичных для хоста skills.
  • Сложнее тестировать в ядре, так как доступность зависит от внешней установки или внедрения.

Рекомендация

Для этого PR используйте Вариант B.

Это сохраняет систему skills в ядре неизменной и предотвращает раскрытие инструкций echarts-fulldata в неподдерживаемых клиентах. Хук рендерера Web Shell остается полезным для любого принадлежащего хосту блочного рендерера, в то время как специфичные для графиков инструкции для модели становятся явным opt-in со стороны хоста.

В долгосрочной перспективе обсудите это как решение о границах продукта/API.

Выбирайте Вариант A, если мейнтейнеры ожидают, что Qwen Code со временем будет поддерживать больше контрактов вывода, рендеримых клиентом. В этом случае required-capabilities — это небольшой общий контракт, который обеспечивает честное предоставление skills в CLI, Web Shell, ACP и будущих клиентах.

Выбирайте Вариант B, если ожидается, что qwencode-viz останется расширением только для Web Shell, и мейнтейнеры не хотят, чтобы skills в ядре зависели от возможностей рендеринга клиента. В этом случае текущий встроенный skill следует удалить из ядра и предоставлять клиентами Web Shell, которые поддерживают echarts-fulldata.

Рекомендуемым значением по умолчанию в будущем является Вариант A, только если мейнтейнеры готовы сделать возможности клиента/сессии частью системы skills. В противном случае оставьте skills хост-рендерера во владении клиента.

Открытые вопросы

  • Должны ли возможности быть ограничены областью действия сессии, запроса или клиента?
  • Должны ли отсутствующие возможности скрывать вызываемые пользователем команды или только скрывать активацию skills, вызываемых моделью?
  • Должны ли имена возможностей быть строками в свободной форме или проверяться по известному реестру?
  • Должны ли недоступные skills полностью скрываться из /skills или отображаться как отключенные с указанием причины?
  • Должен ли существовать ручной override для пользователей, которые намеренно хотят выводить сырые блоки echarts-fulldata в неподдерживаемых клиентах?
  • Должно ли поле называться required-capabilities, requires-capabilities или client-capabilities?

План валидации

Если реализован Вариант A, добавьте тесты для:

  • Парсинга frontmatter в обоих путях парсинга skill.
  • collectAvailableSkillEntries, скрывающего skill при отсутствии возможностей.
  • Того же skill, появляющегося при наличии возможностей.
  • Взаимодействия с paths, skills.disabled и disable-model-invocation.
  • Видимости команд в BundledSkillLoader и SkillCommandLoader.
  • Сопоставления в Web Shell поддерживаемых языков блоков кода с возможностями клиента.
  • Создания сессии Daemon или ACP с сохранением набора возможностей.
  • Существующих интеграционных тестов встроенных skills, чтобы убедиться, что skills без required-capabilities не изменились.

Миграция

Существующие skills не требуют миграции, так как новое поле является опциональным.

Для текущего пути Варианта B удалите skill графиков из встроенных skills ядра. Шаблон пакета Web Shell не должен загружаться ядром автоматически; хосты подключают его, устанавливая или внедряя.

Если принят Вариант A, добавьте:

required-capabilities: - markdown.codeBlock.echarts-fulldata

в будущий встроенный qwencode-viz.

Если принят Вариант B, удалите skill графиков из встроенных skills ядра и задокументируйте, как клиенты Web Shell могут установить или внедрить его при регистрации рендерера echarts-fulldata.

Last updated on