discourse/plugins/discourse-ai/lib/summarization/strategies/base.rb
Roman Rizzi 5a00b47523 SECURITY: Force regeneration for edit-outdated summaries and block stale fallback
Cached topic summaries that became outdated after post edits could remain visible longer than intended, and the 1-hour throttle could delay corrective regeneration. This update makes edit-driven staleness a special case: users who can regenerate summaries now bypass the throttle and refresh immediately, while users who cannot regenerate are not served edit-outdated cached content at all. In practice, stale summaries from edited content are no longer a fallback path, but normal throttle behavior is preserved for non-edit staleness such as newly added posts.

---

**Security Advisory:** https://github.com/discourse/discourse/security/advisories/GHSA-pr9m-5hpq-wc57
2026-03-31 15:12:45 +01:00

57 lines
1.8 KiB
Ruby
Vendored

# frozen_string_literal: true
module DiscourseAi
module Summarization
module Strategies
# Objects inheriting from this class will get passed as a dependency to `DiscourseAi::Summarization::FoldContent`.
# This collaborator knows how to source the content to summarize and the prompts used in the process,
# one for summarizing a chunk and another for concatenating them if necessary.
class Base
def initialize(target)
@target = target
end
attr_reader :target, :opts
# The summary type differentiates instances of `AiSummary` pointing to a single target.
# See the `summary_type` enum for available options.
def type
raise NotImplementedError
end
# @returns { Array<Hash> } - Content to summarize.
#
# This method returns an array of hashes with the content to summarize using the following structure:
#
# {
# poster: A way to tell who write the content,
# id: A number to signal order,
# text: Text to summarize
# }
#
def targets_data
raise NotImplementedError
end
# @returns { Array } - Prompt messages to send to the LLM for summarizing content.
def as_llm_messages(_input)
raise NotImplementedError
end
# Optional lightweight fingerprint for stale cache checks.
# Return a hash with:
# - :original_content_sha (String)
# - :latest_version_at (Time | nil)
# or nil to fallback to full-content stale detection.
def summary_fingerprint
nil
end
# We'll pass this as the feature_name when doing LLM calls.
def feature
"summarize"
end
end
end
end
end