65 lines
1.9 KiB
Ruby
65 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module DiscourseAi
|
|
module Embeddings
|
|
class Manager
|
|
attr_reader :target, :model, :strategy
|
|
|
|
def initialize(target)
|
|
@target = target
|
|
@model =
|
|
DiscourseAi::Embeddings::Models::Base.subclasses.find do
|
|
_1.name == SiteSetting.ai_embeddings_model
|
|
end
|
|
@strategy = DiscourseAi::Embeddings::Strategies::Truncation.new(@target, @model)
|
|
end
|
|
|
|
def generate!
|
|
@strategy.process!
|
|
|
|
# TODO bail here if we already have an embedding with matching version and digest
|
|
|
|
@embeddings = @model.generate_embeddings(@strategy.processed_target)
|
|
|
|
persist!
|
|
end
|
|
|
|
def persist!
|
|
begin
|
|
DB.exec(
|
|
<<~SQL,
|
|
INSERT INTO ai_topic_embeddings_#{table_suffix} (topic_id, model_version, strategy_version, digest, embeddings, created_at, updated_at)
|
|
VALUES (:topic_id, :model_version, :strategy_version, :digest, '[:embeddings]', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
ON CONFLICT (topic_id)
|
|
DO UPDATE SET
|
|
model_version = :model_version,
|
|
strategy_version = :strategy_version,
|
|
digest = :digest,
|
|
embeddings = '[:embeddings]',
|
|
updated_at = CURRENT_TIMESTAMP
|
|
|
|
SQL
|
|
topic_id: @target.id,
|
|
model_version: @model.version,
|
|
strategy_version: @strategy.version,
|
|
digest: @strategy.digest,
|
|
embeddings: @embeddings,
|
|
)
|
|
rescue PG::Error => e
|
|
Rails.logger.error(
|
|
"Error #{e} persisting embedding for topic #{topic.id} and model #{model.name}",
|
|
)
|
|
end
|
|
end
|
|
|
|
def table_suffix
|
|
"#{@model.id}_#{@strategy.id}"
|
|
end
|
|
|
|
def topic_embeddings_table
|
|
"ai_topic_embeddings_#{table_suffix}"
|
|
end
|
|
end
|
|
end
|
|
end
|