Skip to content

fix(templates): curate the agent template catalog — hide fixtures, order starters first (#1513)#1514

Merged
dolho merged 1 commit into
devfrom
feature/1513-curate-template-catalog
Jul 8, 2026
Merged

fix(templates): curate the agent template catalog — hide fixtures, order starters first (#1513)#1514
dolho merged 1 commit into
devfrom
feature/1513-curate-template-catalog

Conversation

@vybe

@vybe vybe commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • GET /api/templates no longer surfaces internal test/canary fixtures, demo agents, or the auto-deployed trinity-system agent as real user templates — they're excluded via an explicit hidden: true template.yaml flag (not fragile name-matching), while staying creatable-by-id so the canary/test harness is untouched.
  • Real starters now lead: both template builders surface a coerced-int priority, so the router's (priority, display_name) sort orders scout/sage/scribe (priority 20) ahead of the dd-* suite.
  • The Templates tab and Create Agent modal now show the same curated set (Templates.vue was GitHub-only).

Acceptance criteria (all met)

  • Fixtures excluded via an explicit signal (hidden: true), not name matching
  • Broken config/agent-templates/cornelius/ stub removed
  • Ordering surfaces real starters first; no fixture outranks a genuine starter
  • Templates tab + CreateAgentModal show the same curated source
  • A test asserts fixtures are excluded (+ a convention guard so they can't silently reappear)

Changes

  • src/backend/services/template_service.py_coerce_priority() helper; surface priority+hidden in _build_local_template, priority in _build_template; filter hidden in get_local_templates() (LIST only — single-id + creation-by-id preserved).
  • config/agent-templates/*/template.yamlhidden: true on the 7 test/canary fixtures, 2 demo agents, and trinity-system.
  • config/agent-templates/scribe/template.yamlquote the usage: value (an unquoted format: colon made the file invalid YAML, so this core starter was silently dropped from the catalog).
  • src/frontend/src/views/Templates.vue — add a Starter (local) Templates section.
  • config/agent-templates/README.md + docs/memory/feature-flows/template-processing.md — reconcile docs with the hidden set and document the flag.
  • tests/unit/test_local_templates_listing.py — exclusion, single-id survival, priority coercion, router-sort regression, real-catalog convention guard.

Notable finds during review

  • Recovered a missing starter: scribe was already absent from the catalog because its template.yaml failed to parse — fixed.
  • Prevented a latent 500: surfacing a raw priority: null/"high" would TypeError the router sort; _coerce_priority guards it (with a regression test).
  • cornelius/ carried no git-tracked files (its only contents are globally gitignored .trinity/ hooks) and never appeared in the catalog (no template.yaml) — removed the local artifact; produces no diff.

Test plan

  • pytest tests/unit/test_local_templates_listing.py — 19 passed (11 existing + 8 new)
  • Adjacent template tests unaffected — test_data_paths_template_surface, test_deploy_writable_templates (5), test_templates (5 passed / 3 skipped)
  • End-to-end catalog simulation against the real config/agent-templates/: fixtures excluded, scout/sage/scribe present and ahead of dd-*, hidden fixtures still resolve by id
  • Manual: Templates tab + Create Agent modal render the same curated set

Follow-up (deferred, out of scope)

  • Extract a shared <TemplateCard> component — the new local card markup mirrors the GitHub card; deferred to avoid pulling CreateAgentModal into a P1 bug fix.

Fixes #1513

🤖 Generated with Claude Code

…er starters first)

GET /api/templates returned every directory under config/agent-templates/, so
internal test/canary fixtures, demo agents, and the auto-deployed system agent
surfaced as real, deployable user templates — undermining onboarding.

- Add an explicit `hidden: true` template.yaml flag (not fragile name-matching)
  on the 7 test/canary fixtures, 2 demo agents, and trinity-system. Filter it
  in get_local_templates() (the LIST) only — get_local_template() and
  creation-by-id still resolve hidden templates, so the canary/test harness
  (canary-fleet.yaml, test_817) is unaffected.
- Surface a coerced-int `priority` in both template builders so the router's
  (priority, display_name) sort actually orders real starters (scout/sage/
  scribe, priority 20) ahead of the rest. _coerce_priority() guards against a
  present-but-null / string / bool value that would otherwise TypeError-500 the
  endpoint (a GitHub template.yaml is untrusted).
- Fix scribe/template.yaml: an unquoted `usage:` value containing `format:`
  made the whole file invalid YAML, so scribe (a core starter) was silently
  dropped from the catalog. Quote it.
- Remove the broken config/agent-templates/cornelius/ stub (only gitignored
  .trinity/ hooks, no template.yaml — untracked, already skipped by the scanner).
- Templates.vue: render a Starter (local) section so the Templates tab shows the
  same curated set as CreateAgentModal (was GitHub-only).
- Reconcile config/agent-templates/README.md with the hidden set + document the
  flag; note the catalog behavior in the template-processing feature flow.
- Tests: exclusion, single-id survival, priority coercion, router-sort
  regression, and a real-catalog convention guard (a future unflagged fixture
  fails CI).

Fixes #1513

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dolho

dolho commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review: ✅ Approve

Clean fix for #1513. Highlights:

  • hidden: true over name-matching — machine-enforced exclusion, surfaced (not filtered) in _build_local_template so single-id resolve + creation-by-id still work for the canary/test harness; only get_local_templates() (LIST) excludes. Right seam.
  • _coerce_priority prevents a real latent 500: a present-but-null/string priority: would TypeError the router's (priority, display_name) sort. Bool-exclusion (isinstance(True, int)) is a nice touch. Regression-tested.
  • Recovered scribe — the unquoted usage: colon made the YAML invalid, silently dropping a core starter. Good catch.
  • Real-catalog convention guard fails CI if a future fixture forgets the flag.

Verified the live template dir is repo-root config/agent-templates/ (template_service._local_templates_dir, line 183), so the flagged set is the one users actually see.

Interaction with #1515: cornelius is added there without hidden (intended — flagship), and lands in the default-priority group. Land this PR first so the coercion guard is in place before cornelius's template.yaml is surfaced.

@dolho dolho merged commit d3365be into dev Jul 8, 2026
20 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