Skip to content

Generate skill tool schemas in SkillFrontmatterField.fromFrontmatter#5482

Merged
jurgenwerk merged 2 commits into
cs-12044-index-time-tool-schema-generation-for-skill-markdown-filefrom
cs-12044-tool-schemas-in-fromfrontmatter
Jul 14, 2026
Merged

Generate skill tool schemas in SkillFrontmatterField.fromFrontmatter#5482
jurgenwerk merged 2 commits into
cs-12044-index-time-tool-schema-generation-for-skill-markdown-filefrom
cs-12044-tool-schemas-in-fromfrontmatter

Conversation

@lukemelia

@lukemelia lukemelia commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Restructures the index-time tool schema generation so the schema work lives in SkillFrontmatterField.fromFrontmatter — the type that owns the skill frontmatter schema — instead of a skill-shape-aware stamping pass inside the generic host file extractor. Addresses the review feedback on the base PR; the observable behavior (stamped file-meta, clean search_doc, diagnostics.toolSchemaErrors) is unchanged.

Shape

skills/my-skill/SKILL.md
        │
        ▼  MarkdownDef.extractAttributes (context: { fileURL, toolContext? })
  SkillFrontmatterField.fromFrontmatter
        │  maps name/description/tools (incl. legacy boxel.commands)
        │  and, when the context carries a toolContext, generates each
        │  tool's LLM definition itself (import.meta.loader + card-api +
        │  basicMappings)
        ▼
  { attributes,            → search doc (tools as authored)
    fileMetaAttributes?,   → file-meta resource (tools + definition stamp)
    diagnostics? }         → merged onto the row's diagnostics
  • FrontmatterField.fromFrontmatter is now async and returns a structured result; the base implementation is unchanged in behavior. Only the skill subclass does tool work — the extractor no longer inspects kind or the tools array.
  • The diagnostics leg of the contract is kind-agnostic: a FrontmatterField subclass contributes a Partial<Diagnostics> bag, and the plumbing (markdown-file-def, the host extractor, the extract response's frontmatterDiagnostics, the file-indexer merge) carries it opaquely. Only SkillFrontmatterField (producer) and the /_indexing-errors surfacing (consumer) name the toolSchemaErrors key.
  • The enriched frontmatter and the diagnostics bag travel from extractAttributes to the extractor on the same out-of-band symbol channels the frontmatter parse error uses (FRONTMATTER_FILE_META_VALUE_SYMBOL, FRONTMATTER_DIAGNOSTICS_SYMBOL), so multi-KB definitions still never land in search_doc.
  • The file-extract render route mints the owner-carrying ToolContext and threads it through extractAttributes options. Its presence is the gate: host-package tools resolve services through the context's owner at construction, and only the indexing path should pay the module-loading cost — interactive extract paths (room file attach, the store's direct fallback) pass none and skip the work. This replaces the generateToolSchemas boolean the base PR used.
  • ToolField's stamped JsonField is renamed tooldefinition (per review). Legacy Skill cards' commands entries now serialize with definition: null rather than tool: null.
  • Base modules value-import basicMappings from @cardstack/runtime-common/helpers/ai, which needs a loader shim in the host's externals (same lazy pattern as marked-sync).
  • Diagnostics row schema and its consumers (indexer merge, /_indexing-errors, boxel-cli formatter) are untouched.

Testing

The existing acceptance coverage (prerender-file-extract-test) exercises the full path — stamping via the render route, search-doc/authored split, broken-tool error attribution, non-skill kinds — and is updated only for the renamed surfaces. Type-check and lint pass across base, host, and runtime-common; host suite runs in CI.

🤖 Generated with Claude Code

…tmatter

Review feedback on the index-time tool schema stamping asked whether the
schema work could live in SkillFrontmatterField.fromFrontmatter instead of a
skill-shape-aware stamping pass inside the generic host file extractor. It
can: fromFrontmatter is now async and receives a context ({ fileURL,
toolContext? }); the skill subclass generates tool definitions itself (via
import.meta.loader, direct card-api import, and basicMappings), and hands
back a structured result. The enriched frontmatter (resource-only) and any
ToolSchemaErrors ride back to the extractor on the same out-of-band symbol
channels the frontmatter parse error uses, so schemas still never land in
search_doc.

The file-extract route now mints the owner-carrying ToolContext and threads
it through extractAttributes options; its presence is what gates the
module-loading schema work to the indexing path.

Also renames the stamped ToolField JsonField from `tool` to `definition`
per review, and adds a loader shim for @cardstack/runtime-common/helpers/ai
so base modules can value-import basicMappings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files  ±0      1 suites  ±0   2h 56m 15s ⏱️ -38s
3 472 tests ±0  3 457 ✅ ±0  15 💤 ±0  0 ❌ ±0 
3 491 runs  ±0  3 476 ✅ ±0  15 💤 ±0  0 ❌ ±0 

Results for commit 2efd971. ± Comparison against earlier commit 1b2f70c.

Realm Server Test Results

    1 files  ±0      1 suites  ±0   11m 20s ⏱️ -9s
1 817 tests ±0  1 817 ✅ ±0  0 💤 ±0  0 ❌ ±0 
1 896 runs  ±0  1 896 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 2efd971. ± Comparison against earlier commit 1b2f70c.

@lukemelia lukemelia requested a review from jurgenwerk July 13, 2026 19:04
Review feedback: naming toolSchemaErrors in FromFrontmatterResult leaked
tool knowledge out of SkillFrontmatterField. The contract is now a
kind-agnostic Partial<Diagnostics> bag — a FrontmatterField subclass
contributes whatever diagnostics keys it owns, and the plumbing
(markdown-file-def symbol channel, host extractor, extract response,
file-indexer merge) carries it opaquely as frontmatterDiagnostics. Only
SkillFrontmatterField (producer) and the /_indexing-errors surfacing
(consumer) name the toolSchemaErrors key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jurgenwerk jurgenwerk merged commit 49d0733 into cs-12044-index-time-tool-schema-generation-for-skill-markdown-file Jul 14, 2026
72 of 73 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants