Skip to content

[Repo Assist] feat: add Tags routing to NotificationCategorizer structured metadata pipeline#196

Closed
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/improve-notificationcategorizer-tags-2026-04-22-33568d2dbf993a95
Closed

[Repo Assist] feat: add Tags routing to NotificationCategorizer structured metadata pipeline#196
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/improve-notificationcategorizer-tags-2026-04-22-33568d2dbf993a95

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This is an automated PR from Repo Assist.

Summary

The Tags field (string[]?) has been present on OpenClawNotification since the structured-metadata overhaul, but the NotificationCategorizer never checked it. Every notification with tags silently fell through to user rules and keyword matching regardless of what those tags said. This PR plugs that gap.

What changed

NotificationCategorizer.cs — adds a Tags step (step 3) in the structured metadata phase:

Intent → Channel → Tags (first known tag) → user rules → keyword fallback

When preferStructuredCategories is true (the default), the categorizer now iterates the Tags array and returns on the first tag that resolves via IntentMap. Unknown tags are silently skipped and fall through. Tags are skipped entirely when preferStructuredCategories is false, consistent with how Intent and Channel are treated.

// 3. Structured metadata: Tags — first tag that maps to a known category wins
if (notification.Tags is { Length: > 0 })
{
    foreach (var tag in notification.Tags)
    {
        if (!string.IsNullOrEmpty(tag) && IntentMap.TryGetValue(tag, out var tagResult))
            return tagResult;
    }
}

Why Tags uses IntentMap

Intent, Channel, and Tags all express gateway-side routing intent; using the same map keeps the vocabulary consistent and avoids a separate data structure.

Backward compatibility

No existing behaviour changes. Notifications without Tags (or with Tags = null) are completely unaffected — the guard Tags is { Length: > 0 } short-circuits immediately.

Trade-offs

  • Tags are checked after Channel — if the gateway sends both a Channel and Tags, Channel wins. This matches the priority ordering (more specific routing → Channel) over free-form routing hints (Tags).
  • Only IntentMap is used for tag lookup (not ChannelMap). Tags are free-form hints, not structured channel names, so the intent vocabulary is the right match.

NotificationCategorizerTests.cs — +18 tests covering:

  • Known tag routes to the correct category
  • All 9 IntentMap values reachable via tag
  • First-match-wins across multiple tags (unknown tags skipped)
  • Unknown-only tags fall through to keywords
  • Priority ordering: intent > channel > tags > user rules > keywords
  • Tags ignored when preferStructuredCategories=false
  • Empty array and null array both fall through

Test Status

Ran locally on Linux runner:

  • Shared.Tests: 648 passed, 20 skipped, 0 failed (was 630; +18 new tests)
  • Tray.Tests: 122 passed, 0 skipped, 0 failed

Build: succeeded, 0 warnings.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

… pipeline

The Tags field on OpenClawNotification was populated by the gateway but
never consulted during classification. Add it as step 3 in the structured
metadata phase (after Intent and Channel, before user rules):

  Intent → Channel → Tags (first known tag) → user rules → keyword fallback

Tags are checked against the existing IntentMap via case-insensitive lookup
so the same category vocabulary applies consistently across all structured
fields. The Tags path is skipped when preferStructuredCategories=false, consistent
with how Intent and Channel are treated.

Add 18 tests covering: known-tag routing, first-match-wins across multiple tags,
unknown tags falling through, priority ordering (intent > channel > tags > user
rules), and behaviour when preferStructuredCategories=false.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@shanselman
Copy link
Copy Markdown
Collaborator

Closing this automated PR. The code is correct and well-tested, but the design choice of Tags overriding User Rules needs more thought — user rules are explicit user intent while tags are free-form gateway hints. Users should be able to override tags with their own rules. If we revisit this, tags should go below user rules in the pipeline priority.

@shanselman shanselman closed this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant