From 58da92a252bd03437b42b1c2d281bb4cb0b2164e Mon Sep 17 00:00:00 2001 From: Pranav Date: Mon, 30 Jun 2025 19:06:25 -0700 Subject: [PATCH] chore: Disable copilot usage after the response count is over (#11845) Disable copilot if the response usage is over. --- config/locales/en.yml | 1 + .../captain/copilot_threads_controller.rb | 15 ++++++++-- .../copilot_threads_controller_spec.rb | 30 ++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index a41a009cf..221f83472 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -270,6 +270,7 @@ en: short_description: 'Sync your contacts and conversations with LeadSquared CRM.' description: 'Sync your contacts and conversations with LeadSquared CRM. This integration automatically creates leads in LeadSquared when new contacts are added, and logs conversation activity to provide your sales team with complete context.' captain: + copilot_message_required: Message is required copilot_error: 'Please connect an assistant to this inbox to use Copilot' copilot_limit: 'You are out of Copilot credits. You can buy more credits from the billing section.' copilot: diff --git a/enterprise/app/controllers/api/v1/accounts/captain/copilot_threads_controller.rb b/enterprise/app/controllers/api/v1/accounts/captain/copilot_threads_controller.rb index 533859b95..8ea85145e 100644 --- a/enterprise/app/controllers/api/v1/accounts/captain/copilot_threads_controller.rb +++ b/enterprise/app/controllers/api/v1/accounts/captain/copilot_threads_controller.rb @@ -23,14 +23,25 @@ class Api::V1::Accounts::Captain::CopilotThreadsController < Api::V1::Accounts:: message: { content: copilot_thread_params[:message] } ) - copilot_message.enqueue_response_job(copilot_thread_params[:conversation_id], Current.user.id) + build_copilot_response(copilot_message) end end private + def build_copilot_response(copilot_message) + if Current.account.usage_limits[:captain][:responses][:current_available].positive? + copilot_message.enqueue_response_job(copilot_thread_params[:conversation_id], Current.user.id) + else + copilot_message.copilot_thread.copilot_messages.create!( + message_type: :assistant, + message: { content: I18n.t('captain.copilot_limit') } + ) + end + end + def ensure_message - return render_could_not_create_error('Message is required') if copilot_thread_params[:message].blank? + return render_could_not_create_error(I18n.t('captain.copilot_message_required')) if copilot_thread_params[:message].blank? end def assistant diff --git a/spec/enterprise/controllers/api/v1/accounts/captain/copilot_threads_controller_spec.rb b/spec/enterprise/controllers/api/v1/accounts/captain/copilot_threads_controller_spec.rb index b8fc628d1..8b561f22a 100644 --- a/spec/enterprise/controllers/api/v1/accounts/captain/copilot_threads_controller_spec.rb +++ b/spec/enterprise/controllers/api/v1/accounts/captain/copilot_threads_controller_spec.rb @@ -86,7 +86,28 @@ RSpec.describe 'Api::V1::Accounts::Captain::CopilotThreads', type: :request do end context 'with valid params' do + it 'returns error when usage limit is exceeded' do + account.limits = { captain_responses: 2 } + account.custom_attributes = { captain_responses_usage: 2 } + account.save! + + post "/api/v1/accounts/#{account.id}/captain/copilot_threads", + params: valid_params, + headers: agent.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:success) + + expect(CopilotMessage.last.message['content']).to eq( + 'You are out of Copilot credits. You can buy more credits from the billing section.' + ) + end + it 'creates a new copilot thread with initial message' do + account.limits = { captain_responses: 2 } + account.custom_attributes = { captain_responses_usage: 0 } + account.save! + expect do post "/api/v1/accounts/#{account.id}/captain/copilot_threads", params: valid_params, @@ -103,8 +124,15 @@ RSpec.describe 'Api::V1::Accounts::Captain::CopilotThreads', type: :request do expect(thread.assistant_id).to eq(assistant.id) message = thread.copilot_messages.last - expect(message.message_type).to eq('user') expect(message.message).to eq({ 'content' => valid_params[:message] }) + + expect(Captain::Copilot::ResponseJob).to have_been_enqueued.with( + assistant: assistant, + conversation_id: valid_params[:conversation_id], + user_id: agent.id, + copilot_thread_id: thread.id, + message: valid_params[:message] + ) end end end