feat: Add temporary account setting to disable Captain auto-resolve (#13680)
Add a temporary `captain_disable_auto_resolve` boolean setting on accounts to prevent Captain from resolving conversations. Guards both the scheduled resolution job and the assistant's resolve tool. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,7 @@ class Account < ApplicationRecord
|
||||
'audio_transcriptions': { 'type': %w[boolean null] },
|
||||
'auto_resolve_label': { 'type': %w[string null] },
|
||||
'keep_pending_on_bot_failure': { 'type': %w[boolean null] },
|
||||
'captain_disable_auto_resolve': { 'type': %w[boolean null] },
|
||||
'conversation_required_attributes': {
|
||||
'type': %w[array null],
|
||||
'items': { 'type': 'string' }
|
||||
@@ -90,6 +91,7 @@ class Account < ApplicationRecord
|
||||
store_accessor :settings, :audio_transcriptions, :auto_resolve_label
|
||||
store_accessor :settings, :captain_models, :captain_features
|
||||
store_accessor :settings, :keep_pending_on_bot_failure
|
||||
store_accessor :settings, :captain_disable_auto_resolve
|
||||
|
||||
has_many :account_users, dependent: :destroy_async
|
||||
has_many :agent_bot_inboxes, dependent: :destroy_async
|
||||
|
||||
@@ -2,6 +2,8 @@ class Captain::InboxPendingConversationsResolutionJob < ApplicationJob
|
||||
queue_as :low
|
||||
|
||||
def perform(inbox)
|
||||
return if inbox.account.captain_disable_auto_resolve
|
||||
|
||||
Current.executed_by = inbox.captain_assistant
|
||||
|
||||
resolvable_conversations = inbox.conversations.pending.where('last_activity_at < ? ', Time.now.utc - 1.hour).limit(Limits::BULK_ACTIONS_LIMIT)
|
||||
|
||||
@@ -12,6 +12,7 @@ module Enterprise::Account::ConversationsResolutionSchedulerJob
|
||||
inbox = captain_inbox.inbox
|
||||
|
||||
next if inbox.email?
|
||||
next if inbox.account.captain_disable_auto_resolve
|
||||
|
||||
Captain::InboxPendingConversationsResolutionJob.perform_later(
|
||||
inbox
|
||||
|
||||
@@ -6,6 +6,7 @@ class Captain::Tools::ResolveConversationTool < Captain::Tools::BasePublicTool
|
||||
conversation = find_conversation(tool_context.state)
|
||||
return 'Conversation not found' unless conversation
|
||||
return "Conversation ##{conversation.display_id} is already resolved" if conversation.resolved?
|
||||
return 'Auto-resolve is disabled for this account' if conversation.account.captain_disable_auto_resolve
|
||||
|
||||
log_tool_usage('resolve_conversation', { conversation_id: conversation.id, reason: reason })
|
||||
|
||||
|
||||
@@ -64,4 +64,15 @@ RSpec.describe Captain::InboxPendingConversationsResolutionJob, type: :job do
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not resolve conversations when auto-resolve is disabled at execution time' do
|
||||
inbox.account.update!(captain_disable_auto_resolve: true)
|
||||
|
||||
expect do
|
||||
described_class.perform_now(inbox)
|
||||
end.not_to(change { resolvable_pending_conversation.reload.status })
|
||||
|
||||
expect(resolvable_pending_conversation.reload.status).to eq('pending')
|
||||
expect(resolvable_pending_conversation.messages.outgoing).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,6 +30,22 @@ RSpec.describe Account::ConversationsResolutionSchedulerJob, type: :job do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account has captain_disable_auto_resolve enabled' do
|
||||
let!(:regular_inbox) { create(:inbox, account: account) }
|
||||
|
||||
before do
|
||||
create(:captain_inbox, captain_assistant: assistant, inbox: regular_inbox)
|
||||
account.update!(captain_disable_auto_resolve: true)
|
||||
end
|
||||
|
||||
it 'does not enqueue resolution jobs' do
|
||||
expect do
|
||||
described_class.perform_now
|
||||
end.not_to have_enqueued_job(Captain::InboxPendingConversationsResolutionJob)
|
||||
.with(regular_inbox)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when inbox has no captain enabled' do
|
||||
let!(:inbox_without_captain) { create(:inbox, account: create(:account)) }
|
||||
|
||||
|
||||
@@ -36,6 +36,17 @@ RSpec.describe Captain::Tools::ResolveConversationTool do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when auto-resolve is disabled for the account' do
|
||||
before { account.update!(captain_disable_auto_resolve: true) }
|
||||
|
||||
it 'does not resolve and returns a disabled message' do
|
||||
result = tool.perform(tool_context, reason: 'Possible spam')
|
||||
|
||||
expect(result).to eq('Auto-resolve is disabled for this account')
|
||||
expect(conversation.reload).not_to be_resolved
|
||||
end
|
||||
end
|
||||
|
||||
describe 'resolving an already resolved conversation' do
|
||||
let(:conversation) { create(:conversation, account: account, inbox: inbox, status: :resolved) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user