discourse-ai/lib/embeddings/entry_point.rb

82 lines
2.9 KiB
Ruby

# frozen_string_literal: true
module DiscourseAi
module Embeddings
class EntryPoint
def inject_into(plugin)
# far-circle-question used by semantic search unavailable tooltip
plugin.register_svg_icon "far-circle-question" if plugin.respond_to?(:register_svg_icon)
# Include random topics in the suggested list *only* if there are no related topics.
plugin.register_modifier(
:topic_view_suggested_topics_options,
) do |suggested_options, topic_view|
related_topics = topic_view.related_topics
include_random = !related_topics || related_topics.topics.length == 0
suggested_options.merge(include_random: include_random)
end
# Query and serialize related topics.
plugin.add_to_class(:topic_view, :related_topics) do
if topic.private_message? || !SiteSetting.ai_embeddings_semantic_related_topics_enabled
return nil
end
@related_topics ||=
::DiscourseAi::Embeddings::SemanticTopicQuery.new(@user).list_semantic_related_topics(
topic,
)
end
# define_method must be used (instead of add_to_class) to make sure
# that method still works when plugin is disabled too
TopicView.alias_method(:categories_old, :categories)
TopicView.define_method(:categories) do
@categories ||= [*categories_old, *related_topics&.categories].flatten.uniq.compact
end
%i[topic_view TopicViewPosts].each do |serializer|
plugin.add_to_serializer(
serializer,
:related_topics,
include_condition: -> { SiteSetting.ai_embeddings_semantic_related_topics_enabled },
) do
if object.next_page.nil? && !object.topic.private_message?
object.related_topics.topics.map do |t|
SuggestedTopicSerializer.new(t, scope: scope, root: false)
end
end
end
end
plugin.register_html_builder("server:topic-show-after-posts-crawler") do |controller|
::DiscourseAi::Embeddings::SemanticRelated.related_topics_for_crawler(controller)
end
# embeddings generation.
callback =
Proc.new do |target|
if SiteSetting.ai_embeddings_enabled &&
(target.is_a?(Topic) || SiteSetting.ai_embeddings_per_post_enabled)
Jobs.enqueue(
:generate_embeddings,
target_id: target.id,
target_type: target.class.name,
)
end
end
plugin.on(:topic_created, &callback)
plugin.on(:topic_edited, &callback)
plugin.on(:post_created, &callback)
plugin.on(:post_edited, &callback)
plugin.add_api_key_scope(
:discourse_ai,
{ search: { actions: %w[discourse_ai/embeddings/embeddings#search] } },
)
end
end
end
end