@@ -6,7 +6,7 @@ class Manager
66 # Get a list of existing concepts
77 # @param limit [Integer, nil] Optional maximum number of concepts to return
88 # @return [Array<InferredConcept>] Array of InferredConcept objects
9- def self . list_concepts ( limit : nil )
9+ def list_concepts ( limit : nil )
1010 query = InferredConcept . all . order ( "name ASC" )
1111
1212 # Apply limit if provided
@@ -21,7 +21,7 @@ def self.list_concepts(limit: nil)
2121 # 2. Process each letter group separately through the deduplicator
2222 # 3. Do a final pass with all deduplicated concepts
2323 # @return [Hash] Statistics about the deduplication process
24- def self . deduplicate_concepts_by_letter ( per_letter_batch : 50 , full_pass_batch : 150 )
24+ def deduplicate_concepts_by_letter ( per_letter_batch : 50 , full_pass_batch : 150 )
2525 # Get all concepts
2626 all_concepts = list_concepts
2727 return if all_concepts . empty?
@@ -42,14 +42,15 @@ def self.deduplicate_concepts_by_letter(per_letter_batch: 50, full_pass_batch: 1
4242
4343 # Process each letter group
4444 letter_deduplicated_concepts = [ ]
45+ finder = DiscourseAi ::InferredConcepts ::Finder . new
4546
4647 letter_groups . each do |letter , concepts |
4748 next if concepts . empty?
4849
4950 batches = concepts . each_slice ( per_letter_batch ) . to_a
5051
5152 batches . each do |batch |
52- result = Finder . deduplicate_concepts ( batch )
53+ result = finder . deduplicate_concepts ( batch )
5354 letter_deduplicated_concepts . concat ( result )
5455 end
5556 end
@@ -60,7 +61,7 @@ def self.deduplicate_concepts_by_letter(per_letter_batch: 50, full_pass_batch: 1
6061
6162 batches = letter_deduplicated_concepts . each_slice ( full_pass_batch ) . to_a
6263 batches . each do |batch |
63- dedups = Finder . deduplicate_concepts ( batch )
64+ dedups = finder . deduplicate_concepts ( batch )
6465 final_result . concat ( dedups )
6566 end
6667
@@ -76,32 +77,34 @@ def self.deduplicate_concepts_by_letter(per_letter_batch: 50, full_pass_batch: 1
7677 # Extract new concepts from arbitrary content
7778 # @param content [String] The content to analyze
7879 # @return [Array<String>] The identified concept names
79- def self . identify_concepts ( content )
80- Finder . identify_concepts ( content )
80+ def identify_concepts ( content )
81+ DiscourseAi :: InferredConcepts :: Finder . new . identify_concepts ( content )
8182 end
8283
8384 # Identify and create concepts from content without applying them to any topic
8485 # @param content [String] The content to analyze
8586 # @return [Array<InferredConcept>] The created or found concepts
86- def self . generate_concepts_from_content ( content )
87+ def generate_concepts_from_content ( content )
8788 return [ ] if content . blank?
8889
8990 # Identify concepts
90- concept_names = Finder . identify_concepts ( content )
91+ finder = DiscourseAi ::InferredConcepts ::Finder . new
92+ concept_names = finder . identify_concepts ( content )
9193 return [ ] if concept_names . blank?
9294
9395 # Create or find concepts in the database
94- Finder . create_or_find_concepts ( concept_names )
96+ finder . create_or_find_concepts ( concept_names )
9597 end
9698
9799 # Generate concepts from a topic's content without applying them to the topic
98100 # @param topic [Topic] A Topic instance
99101 # @return [Array<InferredConcept>] The created or found concepts
100- def self . generate_concepts_from_topic ( topic )
102+ def generate_concepts_from_topic ( topic )
101103 return [ ] if topic . blank?
102104
103105 # Get content to analyze
104- content = Applier . topic_content_for_analysis ( topic )
106+ applier = DiscourseAi ::InferredConcepts ::Applier . new
107+ content = applier . topic_content_for_analysis ( topic )
105108 return [ ] if content . blank?
106109
107110 # Generate concepts from the content
@@ -111,11 +114,12 @@ def self.generate_concepts_from_topic(topic)
111114 # Generate concepts from a post's content without applying them to the post
112115 # @param post [Post] A Post instance
113116 # @return [Array<InferredConcept>] The created or found concepts
114- def self . generate_concepts_from_post ( post )
117+ def generate_concepts_from_post ( post )
115118 return [ ] if post . blank?
116119
117120 # Get content to analyze
118- content = Applier . post_content_for_analysis ( post )
121+ applier = DiscourseAi ::InferredConcepts ::Applier . new
122+ content = applier . post_content_for_analysis ( post )
119123 return [ ] if content . blank?
120124
121125 # Generate concepts from the content
@@ -125,25 +129,25 @@ def self.generate_concepts_from_post(post)
125129 # Match a topic against existing concepts
126130 # @param topic [Topic] A Topic instance
127131 # @return [Array<InferredConcept>] The concepts that were applied
128- def self . match_topic_to_concepts ( topic )
132+ def match_topic_to_concepts ( topic )
129133 return [ ] if topic . blank?
130134
131- Applier . match_existing_concepts ( topic )
135+ DiscourseAi :: InferredConcepts :: Applier . new . match_existing_concepts ( topic )
132136 end
133137
134138 # Match a post against existing concepts
135139 # @param post [Post] A Post instance
136140 # @return [Array<InferredConcept>] The concepts that were applied
137- def self . match_post_to_concepts ( post )
141+ def match_post_to_concepts ( post )
138142 return [ ] if post . blank?
139143
140- Applier . match_existing_concepts_for_post ( post )
144+ DiscourseAi :: InferredConcepts :: Applier . new . match_existing_concepts_for_post ( post )
141145 end
142146
143147 # Find topics that have a specific concept
144148 # @param concept_name [String] The name of the concept to search for
145149 # @return [Array<Topic>] Topics that have the specified concept
146- def self . search_topics_by_concept ( concept_name )
150+ def search_topics_by_concept ( concept_name )
147151 concept = ::InferredConcept . find_by ( name : concept_name )
148152 return [ ] unless concept
149153 concept . topics
@@ -152,7 +156,7 @@ def self.search_topics_by_concept(concept_name)
152156 # Find posts that have a specific concept
153157 # @param concept_name [String] The name of the concept to search for
154158 # @return [Array<Post>] Posts that have the specified concept
155- def self . search_posts_by_concept ( concept_name )
159+ def search_posts_by_concept ( concept_name )
156160 concept = ::InferredConcept . find_by ( name : concept_name )
157161 return [ ] unless concept
158162 concept . posts
@@ -161,11 +165,11 @@ def self.search_posts_by_concept(concept_name)
161165 # Match arbitrary content against existing concepts
162166 # @param content [String] The content to analyze
163167 # @return [Array<String>] Names of matching concepts
164- def self . match_content_to_concepts ( content )
168+ def match_content_to_concepts ( content )
165169 existing_concepts = InferredConcept . all . pluck ( :name )
166170 return [ ] if existing_concepts . empty?
167171
168- Applier . match_concepts_to_content ( content , existing_concepts )
172+ DiscourseAi :: InferredConcepts :: Applier . new . match_concepts_to_content ( content , existing_concepts )
169173 end
170174
171175 # Find candidate topics that are good for concept generation
@@ -179,15 +183,15 @@ def self.match_content_to_concepts(content)
179183 # @option opts [Array<Integer>] :category_ids (nil) Only include topics from these categories
180184 # @option opts [DateTime] :created_after (30.days.ago) Only include topics created after this time
181185 # @return [Array<Topic>] Array of Topic objects that are good candidates
182- def self . find_candidate_topics ( opts = { } )
183- Finder . find_candidate_topics ( **opts )
186+ def find_candidate_topics ( opts = { } )
187+ DiscourseAi :: InferredConcepts :: Finder . new . find_candidate_topics ( **opts )
184188 end
185189
186190 # Find candidate posts that are good for concept generation
187191 # @param opts [Hash] Options to pass to the finder
188192 # @return [Array<Post>] Array of Post objects that are good candidates
189- def self . find_candidate_posts ( opts = { } )
190- Finder . find_candidate_posts ( **opts )
193+ def find_candidate_posts ( opts = { } )
194+ DiscourseAi :: InferredConcepts :: Finder . new . find_candidate_posts ( **opts )
191195 end
192196 end
193197 end
0 commit comments