mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-08-02 11:23:27 +00:00
* FEATURE: add inferred concepts system This commit adds a new inferred concepts system that: - Creates a model for storing concept labels that can be applied to topics - Provides AI personas for finding new concepts and matching existing ones - Adds jobs for generating concepts from popular topics - Includes a scheduled job that automatically processes engaging topics * FEATURE: Extend inferred concepts to include posts * Adds support for concepts to be inferred from and applied to posts * Replaces daily task with one that handles both topics and posts * Adds database migration for posts_inferred_concepts join table * Updates PersonaContext to include inferred concepts Co-authored-by: Roman Rizzi <rizziromanalejandro@gmail.com> Co-authored-by: Keegan George <kgeorge13@gmail.com>
88 lines
2.7 KiB
Ruby
88 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Jobs
|
|
class GenerateConceptsFromPopularItems < ::Jobs::Scheduled
|
|
every 1.day
|
|
|
|
# This job runs daily and generates new concepts from popular topics and posts
|
|
# It selects items based on engagement metrics and generates concepts from their content
|
|
def execute(_args)
|
|
return unless SiteSetting.inferred_concepts_enabled
|
|
|
|
process_popular_topics
|
|
process_popular_posts
|
|
end
|
|
|
|
private
|
|
|
|
def process_popular_topics
|
|
# Find candidate topics that are popular and don't have concepts yet
|
|
manager = DiscourseAi::InferredConcepts::Manager.new
|
|
candidates =
|
|
manager.find_candidate_topics(
|
|
limit: SiteSetting.inferred_concepts_daily_topics_limit || 20,
|
|
min_posts: SiteSetting.inferred_concepts_min_posts || 5,
|
|
min_likes: SiteSetting.inferred_concepts_min_likes || 10,
|
|
min_views: SiteSetting.inferred_concepts_min_views || 100,
|
|
created_after: SiteSetting.inferred_concepts_lookback_days.days.ago,
|
|
)
|
|
|
|
return if candidates.blank?
|
|
|
|
# Process candidate topics - first generate concepts, then match
|
|
Jobs.enqueue(
|
|
:generate_inferred_concepts,
|
|
item_type: "topics",
|
|
item_ids: candidates.map(&:id),
|
|
batch_size: 10,
|
|
)
|
|
|
|
if SiteSetting.inferred_concepts_background_match
|
|
# Schedule a follow-up job to match existing concepts
|
|
Jobs.enqueue_in(
|
|
1.hour,
|
|
:generate_inferred_concepts,
|
|
item_type: "topics",
|
|
item_ids: candidates.map(&:id),
|
|
batch_size: 10,
|
|
match_only: true,
|
|
)
|
|
end
|
|
end
|
|
|
|
def process_popular_posts
|
|
# Find candidate posts that are popular and don't have concepts yet
|
|
manager = DiscourseAi::InferredConcepts::Manager.new
|
|
candidates =
|
|
manager.find_candidate_posts(
|
|
limit: SiteSetting.inferred_concepts_daily_posts_limit || 30,
|
|
min_likes: SiteSetting.inferred_concepts_post_min_likes || 5,
|
|
exclude_first_posts: true,
|
|
created_after: SiteSetting.inferred_concepts_lookback_days.days.ago,
|
|
)
|
|
|
|
return if candidates.blank?
|
|
|
|
# Process candidate posts - first generate concepts, then match
|
|
Jobs.enqueue(
|
|
:generate_inferred_concepts,
|
|
item_type: "posts",
|
|
item_ids: candidates.map(&:id),
|
|
batch_size: 10,
|
|
)
|
|
|
|
if SiteSetting.inferred_concepts_background_match
|
|
# Schedule a follow-up job to match against existing concepts
|
|
Jobs.enqueue_in(
|
|
1.hour,
|
|
:generate_inferred_concepts,
|
|
item_type: "posts",
|
|
item_ids: candidates.map(&:id),
|
|
batch_size: 10,
|
|
match_only: true,
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|