Skip to content

feat: tags on agents, skills, connectors and workflows - #3316

Open
Rotfuks wants to merge 34 commits into
mainfrom
feat/platform-tags
Open

Rotfuks wants to merge 34 commits into
mainfrom
feat/platform-tags

Conversation

@Rotfuks

@Rotfuks Rotfuks commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Rationale

Agents, skills, connectors and workflows each had their own way to group things (repo folders, connector sub-tabs, one workflow category), and none of them cut across types. Free-form tags give one topic facet across the agent platform. Spec: the design note on giantswarm/giantswarm#38901.

This PR carries the agent tags work too (previously planned as its own PR), so all tags ship and get tested together.

Changes

  • Shared code (ui-react): lib/tags.ts (parseTags, MAX_TAGS, suggestions, near-duplicate check), TagsField, TagList, tagsFacet, TagVocabularyProvider, SharedTagsProvider, tagHref. Additive; classic-portal consumers are unchanged.
  • Agents: tags in the wizard and edit flow, on rows and the agent page, Tags facet. Gated on agent-manager get_info capabilities.tags.
  • Skills (gs-backend + agent-platform): read and write frontmatter metadata.tags (comma-joined, other keys kept); Tags facet in SkillsFilterBar (Customize and wizard step), search, card tags, detail row, Add/Edit skill field; the Skill Creator hand-off carries tags.
  • Connectors (muster): MCPServer.getTags(); facet, search, column, detail row; field in register/edit, gated on muster's tool schema declaring tags; GitOps manifest carries the annotation.
  • Connector sub-tabs replaced by tags: "Your connectors / Infrastructure / Internal" is one list now, registered connectors first. Read-only tags infrastructure and agent-platform come from the existing tool-group label. Old sub-tab URLs redirect to ?tags=….
  • Workflows (muster): MusterWorkflow.getTags(); facet, search, column, detail row. Category label unchanged.
  • One vocabulary: suggestions and the "Existing:" hint span all four types across loaded installations. Sources mount only while a tags field is on screen.
  • Tag links: a tag on any detail page opens Customize with that tag preselected; switching tabs keeps it.
  • Rules: ^[a-z0-9]+(-[a-z0-9]+)*$, max 63 characters, unique, at most 50 per item. Writers validate, readers drop malformed entries and never truncate.
  • Docs (agent-platform.md, telemetry.md, urls skill), e2e specs, sitemap data, changesets.

Effect on end users

Agents, skills, connectors and workflows can carry tags: add them when creating or editing, filter and search by them in Customize, and click a tag to see everything with it. The Connectors tab is now a single list; filter by the "infrastructure" or "agent-platform" tag instead of the old sub-tabs.

Background and context

Older muster and agent-manager keep working: the portal hides the field and never sends tags when the backend doesn't declare it.

Testing

  • Unit tests across ui-react, agent-platform, muster, kubernetes-react, gs-backend, app; yarn tsc, lint, prettier, lint:e2e green. ShellSessionsTable flakes on main too.
  • Two code-review passes; findings fixed.
  • Verified in agentlab with muster and agent-manager dev images and tagged fixtures, and clicked through and approved by Dominik.

Ask to reviewers

  • Connector tags render as a "Tags" row under Details; agents, skills and workflows show them under the description, because the connector page has no description section.
  • The derived connector tags live in muster's connectorTags; agent-platform's wizard uses annotation tags only.

MAX_TAGS (50) in ui-react's lib/tags. TagsField refuses a tag past it with "At most 50 tags." and offers no suggestions at the cap; commitTagDraft leaves a draft that would pass it as typed and draftProblem(text, tags) reports it, so the agent, connector and skill forms block Continue/submit. addTags never adds past it. parseTags is unchanged. gs-backend's MAX_SKILL_TAGS points to it.
draftProblem reports "At most 50 tags." while tags read from elsewhere already pass the cap, so a skill edit cannot send what gs-backend refuses. The connector form suggests connectors' own tags, not the read-only tool-group tag. The sitemap drops the retired Infrastructure and Internal connector sub-tabs.
@Rotfuks
Rotfuks requested a review from a team as a code owner October 31, 2026 18:36
@circleci-architect

circleci-architect Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Published Helm chart backstage

3.27.13-reecc69cat20261103141140hc7880dc
Chart backstage
Version 3.27.13-reecc69cat20261103141140hc7880dc
OCI reference oci://gsoci.azurecr.io/charts/giantswarm/backstage:3.27.13-reecc69cat20261103141140hc7880dc
Digest sha256:379c32b130aa2bf47b5ba508fa00c4b8ddc0888cdfe6a190e97087d5327d7973
Registry public — gsoci.azurecr.io
Git catalog giantswarm-operations-platform-test-catalog (index)
Pull this chart
helm pull oci://gsoci.azurecr.io/charts/giantswarm/backstage --version 3.27.13-reecc69cat20261103141140hc7880dc

Posted by architect-orb · build 74964 · commit c7880dc · updated in place on every push

@marians

marians commented Nov 2, 2026

Copy link
Copy Markdown
Member

I could only test the tags feature in the skill creation form.

The font size in tags is currently 10px, which makes them hard to read. Please make them 12px.

Comment thread plugins/ui-react/src/lib/tags.ts Resolved
Comment thread plugins/ui-react/src/lib/tags.ts Resolved
Comment thread CHANGELOG.md Resolved
A tag link reached after clearing the pick (Back, or a link to the same
tag) remounted the tab with the stale empty pick, because the shared tags
were re-seeded in an effect after the tab's filters had read them. ?tags=
is now read with parseTags, so a link in another case or with an invalid
entry still picks the stored tags.
…short near-duplicates

Suggestions matched the whole draft, so a kept invalid part before a comma
stopped every suggestion. Tags under seven characters now count as
near-duplicates at one edit, not two (pods and prod are not one tag).
…lary

ConnectorTagSource counted infrastructure and agent-platform, which come
from a label and no form writes, so every tags field suggested them.
… links

The Connectors and Workflows lists show the section's scoped
installation, so a tag link from a page on another installation opened
a list that may not hold the resource at all.
…or tag suggestions

Step 1 mounted an AgentsDataProvider (every kagent installation, with its
refetch interval) only for tag counts, which the shell's
TagVocabularyProvider overrides wherever the wizard renders. The wizard's
tests now feed suggestions through that provider.
The over-limit check counted tags read from a resource written elsewhere,
even where the Tags field is hidden and nothing writes them, so the
connector and agent edits could never leave their first step (the
connector's Sign-in step sent the person back to it). Only a changed list
is checked now.
Typing into the Tags field dropped its error at the first keystroke, even
while the text stayed wrong. It now follows each change and clears once the
text can be tags, as the forms skill has it.
…lems as the field does

bui's small Badge and Tag are 10px, which the review found hard to read.
The story passed the draft's problem as the form's error, so it showed
while typing, which no form does before a submit.
…nd share the tag rule through gs-common

metadata.tags kept as a YAML list, or with a part that is not a tag, read
as fewer tags than it holds, so a tag change on edit overwrote the rest.
The tag pattern, limits and parser were copied between ui-react and
gs-backend; both now take them from gs-common.
With the sub-tabs gone the Connectors list always holds the platform's own
rows, so its Your connectors empty state never showed and a fresh
installation gave no prompt to add one.
…connector forms

The agent and connector form providers held the same four tag reducers;
both now spread tagsFieldUpdaters.
… catalog tab

ROW_TAGS_MAX was defined on four tabs and the Tags column floor on two,
each meant to match the others; TagList exports both.

@QuentinBisson QuentinBisson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with fixes pushed, please give them a look before merging:

  • An edit that leaves more than 50 stored tags unchanged is no longer blocked.
  • gs-backend refuses (422) to replace skill metadata.tags it cannot read whole (a YAML list or invalid entries), instead of overwriting them.
  • The tag rule now lives once in gs-common.
  • TagsField errors follow the forms skill.
  • "No connectors yet" shows again without the sub-tabs.
  • Shared tag updaters, row count and column width.
    Merge after agent-manager#279 and muster#1740.

… their own component directories

Both were components defined inside another component's directory
(TagsField/TagVocabularyContext.tsx, CatalogFilters/sharedTags.tsx). The
package's exports are unchanged.
With the Connectors sub-tabs gone the hook returns only the Customize
screen and the Connectors list; nothing is a group any more.
…ded, as muster does

gs-common's exceedsTagLimit is the rule muster checks: a list past 50 is
refused only when it holds a tag not already stored. An unchanged or
shortened list of tags written elsewhere goes through; a create takes at
most 50. The skill pull request checks it against the SKILL.md's stored
metadata.tags (a 422) instead of capping every request at 50 in the route,
and renders the SKILL.md before it creates the branch, so a refusal leaves
no branch behind.
…tch no typos under five characters

The Tags field and its helpers take the resource's stored tags: past 50
they may stay, be cut, or be added back once removed; only a new tag is
refused (exceedsTagLimit, the rule muster checks). The skill form passes
its stored tags. One edit no longer makes four-letter tags near-duplicates
(docs and dogs, auth and math).
…fer yields no problem

The form providers read whether tags are offered (muster's create or
update tool schema, agent-manager's tags capability) and check the Tags
field only then, so a hidden field never blocks a step: an edit of a
connector with more than 50 stored tags on a muster without tags no longer
loops from Sign-in back to Connect. The per-page special cases are gone.
The providers also pass the stored tags to the field.

muster's takesTags and takesDisplayName are one takesArgument, and the two
schema hooks one useToolTakesArgument in shared/hooks. The connector router
gives the form provider muster's query client.
@Rotfuks

Rotfuks commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

@marians Tags are drawn at 12px now: 3487370 (TagList and the TagsField chips).

This branch has not been deployed

No deployments
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.

3 participants