# Pull Request Template ## Description Add migrations for document auto-sync Fixes # (issue) ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? locally ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules
74 lines
2.5 KiB
Ruby
74 lines
2.5 KiB
Ruby
# == Schema Information
|
|
#
|
|
# Table name: captain_assistant_responses
|
|
#
|
|
# id :bigint not null, primary key
|
|
# answer :text not null
|
|
# documentable_type :string
|
|
# edited :boolean default(FALSE), not null
|
|
# embedding :vector(1536)
|
|
# question :string not null
|
|
# status :integer default("approved"), not null
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
# account_id :bigint not null
|
|
# assistant_id :bigint not null
|
|
# documentable_id :bigint
|
|
#
|
|
# Indexes
|
|
#
|
|
# idx_cap_asst_resp_on_documentable (documentable_id,documentable_type)
|
|
# index_captain_assistant_responses_on_account_id (account_id)
|
|
# index_captain_assistant_responses_on_assistant_id (assistant_id)
|
|
# index_captain_assistant_responses_on_status (status)
|
|
# vector_idx_knowledge_entries_embedding (embedding) USING ivfflat
|
|
#
|
|
class Captain::AssistantResponse < ApplicationRecord
|
|
self.table_name = 'captain_assistant_responses'
|
|
|
|
belongs_to :assistant, class_name: 'Captain::Assistant'
|
|
belongs_to :account
|
|
belongs_to :documentable, polymorphic: true, optional: true
|
|
has_neighbors :embedding, normalize: true
|
|
|
|
validates :question, presence: true
|
|
validates :answer, presence: true
|
|
|
|
before_validation :ensure_account
|
|
before_validation :ensure_status
|
|
before_validation :mark_as_edited, on: :update
|
|
after_commit :update_response_embedding
|
|
|
|
scope :ordered, -> { order(created_at: :desc) }
|
|
scope :by_account, ->(account_id) { where(account_id: account_id) }
|
|
scope :by_assistant, ->(assistant_id) { where(assistant_id: assistant_id) }
|
|
scope :with_document, ->(document_id) { where(document_id: document_id) }
|
|
|
|
enum status: { pending: 0, approved: 1 }
|
|
|
|
def self.search(query, account_id: nil)
|
|
embedding = Captain::Llm::EmbeddingService.new(account_id: account_id).get_embedding(query)
|
|
nearest_neighbors(:embedding, embedding, distance: 'cosine').limit(5)
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_status
|
|
self.status ||= :approved
|
|
end
|
|
|
|
def mark_as_edited
|
|
self.edited = true if question_changed? || answer_changed?
|
|
end
|
|
|
|
def ensure_account
|
|
self.account = assistant&.account
|
|
end
|
|
|
|
def update_response_embedding
|
|
return unless saved_change_to_question? || saved_change_to_answer? || embedding.nil?
|
|
|
|
Captain::Llm::UpdateEmbeddingJob.perform_later(self, "#{question}: #{answer}")
|
|
end
|
|
end
|