diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/search/SearchIndexUtils.java b/openmetadata-service/src/main/java/org/openmetadata/service/search/SearchIndexUtils.java index ef6788e1eac6..e30073a6ead4 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/search/SearchIndexUtils.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/search/SearchIndexUtils.java @@ -565,7 +565,7 @@ private static void processTagAndTierSources( if (tagFQN == null || labelType == null) { continue; } - String tagSource = labelType.value(); + String tagSource = resolveTagSource(tag, labelType); Map bucket = tagFQN.startsWith("Tier.") ? tagAndTierSources.getTierSources() @@ -574,6 +574,16 @@ private static void processTagAndTierSources( } } + // AI-bot-applied tags count as Generated regardless of labelType, mirroring + // getDescriptionSource. Applier is recorded per-tag in appliedBy (set server-side). + private static String resolveTagSource(TagLabel tag, TagLabel.LabelType labelType) { + String tagSource = labelType.value(); + if (tag.getAppliedBy() != null && AI_BOTS.contains(tag.getAppliedBy())) { + tagSource = TagLabel.LabelType.GENERATED.value(); + } + return tagSource; + } + private static void processEntityTagSources( EntityInterface entity, TagAndTierSources tagAndTierSources) { processTagAndTierSources(entity.getTags(), tagAndTierSources); diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/search/SearchIndexUtilsTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/search/SearchIndexUtilsTest.java index a06c3c5253ee..3aeed782649b 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/search/SearchIndexUtilsTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/search/SearchIndexUtilsTest.java @@ -219,6 +219,34 @@ void testDescriptionAndTagSourceProcessing() { assertEquals(2, descriptionSources.get(ChangeSource.SUGGESTED.value())); } + @Test + void testAiBotAppliedTagsCountAsGenerated() { + TagLabel botTag = + new TagLabel() + .withTagFQN("PII.Sensitive") + .withLabelType(TagLabel.LabelType.MANUAL) + .withAppliedBy("collateaiapplicationbot"); + TagLabel botTier = + new TagLabel() + .withTagFQN("Tier.Tier1") + .withLabelType(TagLabel.LabelType.MANUAL) + .withAppliedBy("aiautomationapplicationbot"); + TagLabel humanTag = + new TagLabel() + .withTagFQN("PersonalData.Personal") + .withLabelType(TagLabel.LabelType.MANUAL) + .withAppliedBy("analyst"); + Table table = new Table().withTags(List.of(botTag, botTier, humanTag)); + + SearchIndexUtils.TagAndTierSources tagAndTierSources = + SearchIndexUtils.processTagAndTierSources(table); + + assertEquals(1, tagAndTierSources.getTagSources().get(TagLabel.LabelType.GENERATED.value())); + assertEquals(1, tagAndTierSources.getTierSources().get(TagLabel.LabelType.GENERATED.value())); + assertEquals(1, tagAndTierSources.getTagSources().get(TagLabel.LabelType.MANUAL.value())); + assertNull(tagAndTierSources.getTierSources().get(TagLabel.LabelType.MANUAL.value())); + } + @Test void testSearchAggregationBuilderHelpers() { SearchAggregationNode termNode = SearchAggregation.terms("team", "owner.name", 25);