diff --git a/enterprise/app/models/captain/document.rb b/enterprise/app/models/captain/document.rb index 99b9d8cb8..f9fc62d79 100644 --- a/enterprise/app/models/captain/document.rb +++ b/enterprise/app/models/captain/document.rb @@ -65,6 +65,7 @@ class Captain::Document < ApplicationRecord after_create_commit :update_document_usage after_destroy :update_document_usage after_commit :enqueue_response_builder_job + after_commit :enqueue_chunk_builder_job scope :ordered, -> { order(created_at: :desc) } scope :for_account, ->(account_id) { where(account_id: account_id) } @@ -116,6 +117,12 @@ class Captain::Document < ApplicationRecord Captain::Documents::ResponseBuilderJob.perform_later(self) end + def enqueue_chunk_builder_job + return unless should_enqueue_chunk_builder_job? + + Captain::Documents::ChunkBuilderJob.perform_later(self) + end + def should_enqueue_response_builder? return false if destroyed? return false unless available? @@ -125,6 +132,20 @@ class Captain::Document < ApplicationRecord (saved_change_to_status? || saved_change_to_content?) && content.present? end + def should_enqueue_chunk_builder_job? + return false unless chunk_builder_enabled? + return false if destroyed? + return false unless available? + return false if pdf_document? + + (saved_change_to_status? || saved_change_to_content?) && content.present? + end + + def chunk_builder_enabled? + value = InstallationConfig.find_by(name: 'CAPTAIN_DOCUMENT_CHUNKING_ENABLED')&.value + ActiveModel::Type::Boolean.new.cast(value) + end + def update_document_usage account.update_document_usage end diff --git a/spec/enterprise/models/captain/document_spec.rb b/spec/enterprise/models/captain/document_spec.rb index e6543e0d7..a27ad8c1d 100644 --- a/spec/enterprise/models/captain/document_spec.rb +++ b/spec/enterprise/models/captain/document_spec.rb @@ -250,4 +250,53 @@ RSpec.describe Captain::Document, type: :model do end.not_to have_enqueued_job(Captain::Documents::ResponseBuilderJob) end end + + describe 'chunk builder job callback' do + before do + clear_enqueued_jobs + InstallationConfig.find_or_initialize_by(name: 'CAPTAIN_DOCUMENT_CHUNKING_ENABLED').update!(value: 'true') + end + + it 'enqueues for available non-PDF documents with content' do + expect do + create(:captain_document, assistant: assistant, account: account, status: :available, content: 'Doc content') + end.to have_enqueued_job(Captain::Documents::ChunkBuilderJob) + end + + it 'does not enqueue when chunking flag is disabled' do + InstallationConfig.find_or_initialize_by(name: 'CAPTAIN_DOCUMENT_CHUNKING_ENABLED').update!(value: 'false') + + expect do + create(:captain_document, assistant: assistant, account: account, status: :available, content: 'Doc content') + end.not_to have_enqueued_job(Captain::Documents::ChunkBuilderJob) + end + + it 'does not enqueue for PDF documents' do + document = build(:captain_document, assistant: assistant, account: account, status: :available, content: nil) + document.pdf_file.attach( + io: StringIO.new('PDF content'), + filename: 'sample.pdf', + content_type: 'application/pdf' + ) + + expect do + document.save! + end.not_to have_enqueued_job(Captain::Documents::ChunkBuilderJob) + end + + it 'enqueues when content is updated on available non-PDF document' do + document = create( + :captain_document, + assistant: assistant, + account: account, + status: :available, + content: nil + ) + clear_enqueued_jobs + + expect do + document.update!(content: 'Updated document content') + end.to have_enqueued_job(Captain::Documents::ChunkBuilderJob) + end + end end