# frozen_string_literal: true # TODO(@keegan): Remove after removing SiteSetting.summarization_strategy # Keeping because its still needed for SiteSetting to function. # Remove after settings are migrated to AI # Base class that defines the interface that every summarization # strategy must implement. # Above each method, you'll find an explanation of what # it does and what it should return. module Summarization class Base class << self def available_strategies DiscoursePluginRegistry.summarization_strategies end def find_strategy(strategy_model) available_strategies.detect { |s| s.model == strategy_model } end def selected_strategy return if SiteSetting.summarization_strategy.blank? find_strategy(SiteSetting.summarization_strategy) end def can_see_summary?(target, user) return false if SiteSetting.summarization_strategy.blank? return false if target.class == Topic && target.private_message? has_cached_summary = SummarySection.exists?(target: target, meta_section_id: nil) return has_cached_summary if user.nil? has_cached_summary || can_request_summary_for?(user) end def can_request_summary_for?(user) return false unless user user_group_ids = user.group_ids SiteSetting.custom_summarization_allowed_groups_map.any? do |group_id| user_group_ids.include?(group_id) end end end # Some strategies could require other conditions to work correctly, # like site settings. # This method gets called when admins attempt to select it, # checking if we met those conditions. def correctly_configured? raise NotImplemented end # Strategy name to display to admins in the available strategies dropdown. def display_name raise NotImplemented end # If we don't meet the conditions to enable this strategy, # we'll display this hint as an error to admins. def configuration_hint raise NotImplemented end # The idea behind this method is "give me a collection of texts, # and I'll handle the summarization to the best of my capabilities.". # It's important to emphasize the "collection of texts" part, which implies # it's not tied to any model and expects the "content" to be a hash instead. # # @param content { Hash } - Includes the content to summarize, plus additional # context to help the strategy produce a better result. Keys present in the content hash: # - resource_path (optional): Helps the strategy build links to the content in the summary (e.g. "/t/-/:topic_id/POST_NUMBER") # - content_title (optional): Provides guidance about what the content is about. # - contents (required): Array of hashes with content to summarize (e.g. [{ poster: "asd", id: 1, text: "This is a text" }]) # All keys are required. # @param &on_partial_blk { Block - Optional } - If the strategy supports it, the passed block # will get called with partial summarized text as its generated. # # @param current_user { User } - User requesting the summary. # # @returns { Hash } - The summarized content, plus chunks if the content couldn't be summarized in one pass. Example: # { # summary: "This is the final summary", # chunks: [ # { ids: [topic.first_post.post_number], summary: "this is the first chunk" }, # { ids: [post_1.post_number, post_2.post_number], summary: "this is the second chunk" }, # ], # } def summarize(content, current_user) raise NotImplemented end # Returns the string we'll store in the selected strategy site setting. def model raise NotImplemented end end end