CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes45downloads
skill-required-capabilities.md467 linesDownload Raw Back to design
1# Skill Required Capabilities Design2 3Status: design note; this PR proceeds with Option B and leaves4`required-capabilities` as a future proposal.5 6## Context7 8Web Shell can render custom fenced code blocks through its markdown renderer. The9chart renderer proposal uses an `echarts-fulldata` fenced code block so the model10can return a complete ECharts option and dataset payload that Web Shell renders11as an interactive chart.12 13That output contract is only useful in clients that can render it. In the CLI,14ACP clients, or any other surface without a matching renderer, the same response15would appear as a large code block instead of a chart.16 17The initial bundled chart skill proposal relied on wording to tell the model18that the format is for Web Shell. This is a soft guard. If the skill is exposed19in a non-Web-Shell session, the model can still choose an output format that the20client cannot render.21 22For the current PR, Qwen Code keeps the renderer extension point in Web Shell23but does not bundle `qwencode-viz` in core. The Web Shell package includes a24copyable, non-auto-loaded skill template, and hosts should install or inject25that skill only when they also register an `echarts-fulldata` renderer.26 27## Problem28 29Qwen Code needs a clear way to decide whether a host-specific skill should be30shown to the model and to users.31 32For `qwencode-viz`, the concrete question is:33 34- Should core support a generic `required-capabilities` skill metadata field?35- Or should `qwencode-viz` not be a core bundled skill at all, and instead be36  supplied only by Web Shell clients that install or inject it?37 38## Goals39 40- Prevent renderer-specific skills from being exposed when the current client41  cannot satisfy their output contract.42- Keep startup skill reminders, explicit skill activation, slash-command43  discovery, and skill validation consistent.44- Avoid hardcoding `qwencode-viz` as a special case.45- Preserve existing skill behavior when no capability requirement is declared.46- Keep the design extensible for future host capabilities, not only ECharts.47 48## Non-goals49 50- Implementing the ECharts renderer itself.51- Redesigning all client/server capability negotiation.52- Changing the semantics of existing skill frontmatter.53- Solving multi-client shared-session capability changes in the first version.54 55## Current Related Mechanisms56 57The codebase already has several visibility controls, but none represent client58rendering capabilities:59 60- `disable-model-invocation`: prevents a skill from being auto-invoked by the61  model.62- `user-invocable`: controls whether a bundled skill is available as a command.63- `paths`: scopes skill availability to matching workspace paths.64- `skills.disabled`: disables configured skills.65- `allowedTools`: currently used by bundled skill loading to hide cron-oriented66  skills when cron tools are unavailable.67- Slash command `supportedModes`: filters commands by execution mode.68- Daemon and ACP capability objects: describe protocol or client support, but69  are not currently connected to skill exposure.70 71There is no existing `required-capabilities` or equivalent skill frontmatter.72Adding it would be a new skill contract.73 74## Option A: Add `required-capabilities`75 76Add a generic skill frontmatter field:77 78```yaml79---80name: qwencode-viz81description: Render analytical charts in Web Shell using echarts-fulldata fenced code blocks.82required-capabilities:83  - markdown.codeBlock.echarts-fulldata84---85```86 87When the current client/session does not advertise all listed capabilities, the88skill is treated as unavailable.89 90### Capability Naming91 92Use namespaced string capabilities:93 94```text95markdown.codeBlock.echarts-fulldata96```97 98This keeps the field generic while making the contract precise:99 100- `markdown`: the capability belongs to rendered markdown.101- `codeBlock`: the capability applies to fenced code block rendering.102- `echarts-fulldata`: the specific language/info string supported by the103  renderer.104 105Future examples could be:106 107- `markdown.codeBlock.vega-lite`108- `markdown.codeBlock.mermaid-interactive`109- `artifact.openUrl`110 111### Skill Metadata112 113Add `requiredCapabilities?: string[]` to skill configuration after parsing the114frontmatter key `required-capabilities`.115 116Both skill parsing paths should understand the field:117 118- `packages/core/src/skills/skill-load.ts`119- `packages/core/src/skills/skill-manager.ts`120 121The field should be optional. Missing or empty means the skill has no client122capability requirement.123 124### Runtime Capability Source125 126Add client/session capabilities to the runtime config:127 128```ts129interface ConfigParameters {130  clientCapabilitiesProvider?: () => ReadonlySet<string>;131}132```133 134Expose a helper on `Config`, for example:135 136```ts137config.getClientCapabilities(): ReadonlySet<string>138```139 140Then centralize the check:141 142```ts143function skillMeetsRequiredCapabilities(skill: Skill, config: Config): boolean {144  return skill.config.requiredCapabilities.every((capability) =>145    config.getClientCapabilities().has(capability),146  );147}148```149 150### Filtering Points151 152The capability filter should be applied before skills are exposed to either the153model or the user:154 155- `collectAvailableSkillEntries` in `packages/core/src/tools/skill-utils.ts`156  should skip skills whose required capabilities are missing. This keeps startup157  skill reminders, delta reminders, `SkillTool` validation, and model-invocable158  activation aligned.159- `BundledSkillLoader` should skip unavailable bundled skills when creating160  user-facing commands.161- `SkillCommandLoader` should skip unavailable file-system skills when creating162  user-facing commands.163 164The important invariant is that a skill hidden from the model should not still165appear as an invocable command unless the project intentionally supports a166manual override.167 168### Web Shell Registration169 170Web Shell should advertise renderer support explicitly rather than relying on171the presence of an opaque `renderCodeBlock` callback.172 173For example:174 175```tsx176<WebShell177  customization={{178    markdown: {179      renderableCodeBlockLanguages: ['echarts-fulldata'],180      renderCodeBlock(info) {181        // render custom blocks182      },183    },184  }}185/>186```187 188The Web Shell client can map that to:189 190```text191markdown.codeBlock.echarts-fulldata192```193 194This makes the capability declaration stable even if the renderer callback195contains custom logic, fallbacks, or multiple supported languages.196 197### Daemon and ACP Propagation198 199For hosted or daemon-based sessions, the client capability set needs to reach200core before skills are loaded or listed. A minimal version can pass capabilities201when creating a session:202 203```ts204interface CreateSessionRequest {205  clientCapabilities?: string[];206}207```208 209The daemon bridge, SDK, and ACP session creation flow can store this as210session-scoped config.211 212For the first version, capabilities can be session-scoped. If multiple clients213attach to the same session, the behavior should be documented as using the214capabilities from session creation time.215 216### Pros217 218- Keeps `qwencode-viz` as one canonical bundled skill.219- Prevents host-specific output contracts from leaking into unsupported220  clients.221- Creates a reusable mechanism for future renderer-specific or host-specific222  skills.223- Makes the dependency explicit and testable.224 225### Cons226 227- Adds a new cross-cutting skill metadata field.228- Requires client/session capability plumbing across Web Shell, daemon, SDK, and229  ACP surfaces.230- Needs careful documentation for shared-session behavior.231- May be more machinery than needed if `qwencode-viz` is the only expected232  capability-gated skill.233 234## Option B: Client-Supplied Skill235 236Do not add a generic `required-capabilities` field. Instead, avoid bundling237`qwencode-viz` in core. The Web Shell client, or any client that supports the238renderer, supplies the skill itself.239 240Possible distribution models:241 242- The Web Shell host installs `.qwen/skills/qwencode-viz/SKILL.md`.243- The Web Shell package ships an optional non-auto-loaded skill template that a244  host can copy or install when chart rendering is enabled.245- The Web Shell integration ships an extension skill package.246- The Web Shell integration injects equivalent model instructions only when its247  chart renderer is enabled.248 249In this model, the skill is available only because the rendering client chose to250provide it.251 252### Web Shell Host Integration253 254A Web Shell host that wants chart output should opt in to both halves of the255contract:256 2571. Register an `echarts-fulldata` Markdown code block renderer.2582. Provide the matching chart skill from259   `packages/web-shell/docs/examples/qwencode-viz/SKILL.md`.260 261For example:262 263```tsx264import * as echarts from 'echarts';265import {266  WebShellWithProviders,267  createEchartsFullDataRenderer,268} from '@qwen-code/web-shell';269 270<WebShellWithProviders271  baseUrl="http://127.0.0.1:4170"272  token={token}273  sessionId={sessionId}274  markdown={{275    renderCodeBlock: createEchartsFullDataRenderer({276      loadEcharts: () => echarts,277      resolveDataRef: async (ref, meta) =>278        loadControlledChartDataset(ref, meta),279    }),280  }}281/>;282```283 284In this renderer configuration, `loadEcharts` lets the host provide the285approved ECharts runtime, either as a static import or a lazy-loaded module.286`resolveDataRef` is only used for `data.kind="ref"` chart blocks; it is the287host-owned bridge from a model-visible data reference to a trusted dataset.288The model-facing envelope format is described by the optional skill template in289`packages/web-shell/docs/examples/qwencode-viz/SKILL.md`; the renderer-side290validation lives in291`packages/web-shell/client/components/messages/EchartsFullDataBlock.tsx`.292 293The skill file should be installed or injected only by hosts that perform this294registration. A simple file-based integration can copy:295 296```text297packages/web-shell/docs/examples/qwencode-viz/SKILL.md298```299 300to the workspace or user skill directory, for example:301 302```text303.qwen/skills/qwencode-viz/SKILL.md304```305 306An integration with its own skill distribution layer can instead load the same307file as the canonical source content and expose it through that layer. In both308cases, core does not auto-load the skill; the host owns enabling it because the309host owns the renderer.310 311For `data.kind="ref"` envelopes, the built-in renderer validates that `data.ref`312uses a normalized `artifact://` or `session-file://` reference before it calls313the host-controlled `resolveDataRef(ref, meta)` implementation. The renderer314also parses the block as JSON and sanitizes the ECharts option before rendering;315it does not evaluate model-provided JavaScript, fetch arbitrary URLs, or read316local files by itself. A custom renderer should preserve the same split:317renderer-level JSON/ref/option validation first, host-owned artifact resolution318second.319 320A daemon-backed host can treat the workspace file API as one artifact backend.321For example, the host can persist chart artifacts under a controlled workspace322directory such as `.qwen/artifacts/`, expose model-facing references like323`artifact://chart-data/orders.csv`, and resolve them through daemon324`GET /file?path=.qwen/artifacts/chart-data/orders.csv`. This keeps325`artifact://` as the public chart contract while allowing the first326implementation to reuse daemon workspace files.327 328The resolver must still enforce the artifact root before calling the daemon:329 330```tsx331const ARTIFACT_ROOT = '.qwen/artifacts/';332const MAX_CHART_DATA_BYTES = 256 * 1024;333 334async function resolveDataRef(335  ref: string,336  meta: { format?: string; dimensions?: string[] },337) {338  const artifactPrefix = 'artifact://';339  if (!ref.startsWith(artifactPrefix)) {340    throw new Error(`Unsupported chart data ref: ${ref}`);341  }342 343  const artifactPath = ref.slice(artifactPrefix.length);344  if (345    artifactPath.length === 0 ||346    artifactPath.startsWith('/') ||347    artifactPath.includes('\\') ||348    artifactPath.split('/').includes('..')349  ) {350    throw new Error(`Invalid chart data ref: ${ref}`);351  }352 353  const url = new URL('/file', daemonBaseUrl);354  url.searchParams.set('path', `${ARTIFACT_ROOT}${artifactPath}`);355  url.searchParams.set('maxBytes', String(MAX_CHART_DATA_BYTES));356 357  const response = await fetch(url, {358    headers: token ? { Authorization: `Bearer ${token}` } : undefined,359  });360  if (!response.ok) {361    throw new Error(`Failed to read chart data: ${response.status}`);362  }363 364  const file = (await response.json()) as { content: string };365  return meta.format === 'csv'366    ? parseCsvAsArrayRows(file.content, meta.dimensions)367    : JSON.parse(file.content);368}369```370 371This example intentionally maps only normalized `artifact://` paths under372`.qwen/artifacts/`. If a host later moves artifacts to object storage or a373session-scoped artifact service, only `resolveDataRef` needs to change; the374model-facing `echarts-fulldata` block can keep using the same ref shape.375 376### Pros377 378- Minimal core change.379- No new global skill metadata contract.380- Capability availability is naturally owned by the client that implements the381  renderer.382- Avoids daemon or ACP plumbing unless the client already has a skill injection383  mechanism.384 385### Cons386 387- No canonical bundled skill unless all clients copy the same content.388- More burden on each Web Shell integrator.389- Users moving between clients may see inconsistent skill availability.390- Does not create a general safeguard for future host-specific skills.391- Harder to test in core because availability depends on external installation392  or injection.393 394## Recommendation395 396For this PR, use Option B.397 398That keeps the core skill system unchanged and avoids exposing399`echarts-fulldata` instructions in unsupported clients. The Web Shell renderer400hook remains useful for any host-owned block renderer, while chart-specific401model instructions become an explicit host opt-in.402 403Longer term, discuss this as a product/API boundary decision.404 405Choose Option A if maintainers expect Qwen Code to support more client-rendered406output contracts over time. In that case, `required-capabilities` is a small407general contract that keeps skill exposure honest across CLI, Web Shell, ACP,408and future clients.409 410Choose Option B if `qwencode-viz` is expected to remain a Web-Shell-only411extension and maintainers do not want core skills to depend on client rendering412features. In that case, the current bundled skill should be removed from core413and supplied by Web Shell clients that support `echarts-fulldata`.414 415The recommended future default is Option A only if maintainers are comfortable416making client/session capabilities part of the skill system. Otherwise, keep417host-renderer skills client-owned.418 419## Open Questions420 421- Should capabilities be session-scoped, request-scoped, or client-scoped?422- Should missing capabilities hide user-invocable commands, or only hide423  model-invocable skill activation?424- Should capability names be free-form strings or validated against a known425  registry?426- Should unavailable skills be hidden entirely from `/skills`, or shown as427  disabled with a reason?428- Should there be a manual override for users who intentionally want to emit raw429  `echarts-fulldata` blocks in unsupported clients?430- Should the field name be `required-capabilities`, `requires-capabilities`, or431  `client-capabilities`?432 433## Validation Plan434 435If Option A is implemented, add tests for:436 437- Frontmatter parsing in both skill parsing paths.438- `collectAvailableSkillEntries` hiding a skill when capabilities are missing.439- The same skill appearing when capabilities are present.440- Interaction with `paths`, `skills.disabled`, and `disable-model-invocation`.441- `BundledSkillLoader` and `SkillCommandLoader` command visibility.442- Web Shell mapping from supported code block languages to client capabilities.443- Daemon or ACP session creation preserving the capability set.444- Existing bundled skill integration tests, to ensure skills without445  `required-capabilities` are unchanged.446 447## Migration448 449Existing skills require no migration because the new field is optional.450 451For the current Option B path, remove the chart skill from core bundled skills.452The Web Shell package template must not be loaded by core automatically; hosts453opt in by installing or injecting it.454 455If Option A is accepted, add:456 457```yaml458required-capabilities:459  - markdown.codeBlock.echarts-fulldata460```461 462to a future bundled `qwencode-viz`.463 464If Option B is accepted, remove the chart skill from core bundled skills and465document how Web Shell clients can install or inject it when they register an466`echarts-fulldata` renderer.467 
basant307/AI_Governance_Project · CoolFace