Skip to content

Class HTM::TagService

Inherits Object
Defined in lib/htm/tag_service.rb

Tag Service - Processes and validates hierarchical tags

This service wraps the configured tag extractor and provides: * Response parsing (string or array) * Format validation (lowercase, alphanumeric, hyphens, colons) * Depth validation (max 5 levels) * Ontology consistency * Circuit breaker protection for external LLM failures

The actual LLM call is delegated to HTM.configuration.tag_extractor

Constants

SINGULARIZE_SKIP_LIST

Words that should NOT be singularized (proper nouns, technical terms, etc.)

TAG_FORMAT

Validation regex

Public Class Methods

circuit_breaker()

Get or create the circuit breaker for tag service - @return [HTM::CircuitBreaker] The circuit breaker instance

extract(content, existing_ontology: [])

Extract tags with validation and processing - @param content [String] Text to analyze - @param existing_ontology [Array] Sample of existing tags for context - @raise [CircuitBreakerOpenError] If circuit breaker is open - @return [Array] Validated tag names

max_depth()

Maximum tag hierarchy depth (configurable, default 4) - @return [Integer] Max depth (3 colons max by default)

parse_hierarchy(tag)

Parse hierarchical structure of a tag - @param tag [String] Hierarchical tag (e.g., "ai:llm:embedding") - @return [Hash] Hierarchy structure { full: "ai:llm:embedding", root: "ai", parent: "ai:llm", levels: ["ai", "llm", "embedding"], depth: 3 }

parse_tags(raw_tags)

Parse tag response (handles string or array input) - @param raw_tags [String, Array] Raw response from extractor - @return [Array] Parsed tag strings

reset_circuit_breaker!()

Reset the circuit breaker (useful for testing) - @return [void]

singularize_level(level)

Singularize a single tag level with safety checks - @param level [String] Single tag level - @return [String] Singularized level or original if skipped

singularize_tag_levels(tag)

Normalize tag levels to singular form

Converts plural levels to singular using ActiveSupport's singularize. This ensures taxonomy consistency (e.g., "users" -> "user").

Skips: * Proper nouns and technical terms (Rails, MkDocs, etc.) * Words ending in -ics (analytics, robotics, etc.) * Words that don't end in common plural patterns - @param tag [String] Tag with potentially plural levels - @return [String] Tag with all levels singularized

valid_tag?(tag)

Validate single tag format - @param tag [String] Tag to validate - @return [Boolean] True if valid

validate_and_filter_tags(tags)

Validate and filter tags - @param tags [Array] Parsed tags - @return [Array] Valid tags only