From 38dbda9378877bb8fdbcb1d88ae57bf51f9be971 Mon Sep 17 00:00:00 2001 From: Aakash Bakhle <48802744+aakashb95@users.noreply.github.com> Date: Tue, 17 Mar 2026 17:36:40 +0530 Subject: [PATCH 1/2] fix: reverse order of api_key for bg task (#13826) # Pull Request Template ## Description we were getting 403, 401 errors on `translate_query` on langfuse and sentry This happened because, we use the customer's openai key if they have BYOK But translation is something they never opt in so we should not use their quota for it. This PR addresses the issue. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. 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 --- .../app/services/captain/llm/translate_query_service.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/enterprise/app/services/captain/llm/translate_query_service.rb b/enterprise/app/services/captain/llm/translate_query_service.rb index 404a44755..bdff88150 100644 --- a/enterprise/app/services/captain/llm/translate_query_service.rb +++ b/enterprise/app/services/captain/llm/translate_query_service.rb @@ -26,6 +26,12 @@ class Captain::Llm::TranslateQueryService < Captain::BaseTaskService 'translate_query' end + # Translation is an internal operation, not customer-initiated. + # Prefer the system key; fall back to the account's hook key for self-hosted setups without one. + def api_key + @api_key ||= system_api_key.presence || openai_hook&.settings&.dig('api_key') + end + def query_in_target_language?(query) detector = CLD3::NNetLanguageIdentifier.new(0, 1000) result = detector.find_language(query) From 4d344a47dc951ef95e809af06032cbc5aca86aac Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com> Date: Tue, 17 Mar 2026 20:35:03 +0530 Subject: [PATCH 2/2] chore(tds-1): rake task for assignment v2 migration (#13828) --- lib/tasks/assignment_v2_migration.rake | 81 ++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 lib/tasks/assignment_v2_migration.rake diff --git a/lib/tasks/assignment_v2_migration.rake b/lib/tasks/assignment_v2_migration.rake new file mode 100644 index 000000000..4fe938fd0 --- /dev/null +++ b/lib/tasks/assignment_v2_migration.rake @@ -0,0 +1,81 @@ +# Migrate max_assignment_limit to Agent Capacity Policies +# +# Converts legacy per-inbox max_assignment_limit settings into +# AgentCapacityPolicy records used by Assignment V2. +# +# Usage Examples: +# # Migrate a single account +# ACCOUNT_ID=1 bundle exec rake assignment_v2:migrate +# +# # Migrate all accounts in the installation +# bundle exec rake assignment_v2:migrate +# +# Parameters: +# ACCOUNT_ID: (optional) ID of the account to migrate. If omitted, migrates all accounts. +# +# rubocop:disable Metrics/BlockLength +namespace :assignment_v2 do + desc 'Migrate max_assignment_limit inbox settings to agent capacity policies' + task migrate: :environment do + int_max = (2**31) - 1 + policy_name = 'Auto Assignment Capacity' + + account_id = ENV.fetch('ACCOUNT_ID', nil) + accounts = account_id.present? ? Account.where(id: account_id) : Account.all + + if account_id.blank? + print 'No ACCOUNT_ID specified. This will migrate ALL accounts. Continue? [y/N] ' + abort 'Aborted.' unless $stdin.gets.chomp.casecmp('y').zero? + end + + if account_id.present? && accounts.empty? + puts "Error: Account with ID #{account_id} not found" + exit(1) + end + + total = accounts.count + puts "Migrating assignment policies for #{total} account(s)..." + puts "Started at: #{Time.current}" + + migrated = 0 + skipped = 0 + errored = 0 + + accounts.find_each do |account| + inboxes_with_limit = account.inboxes.where("auto_assignment_config->>'max_assignment_limit' ~ '[1-9]'") + + if inboxes_with_limit.empty? + skipped += 1 + puts " [#{migrated + skipped + errored}/#{total}] Account #{account.id} — skipped (no inboxes with limit)" + next + end + + ActiveRecord::Base.transaction do + policy = AgentCapacityPolicy.find_or_create_by!(account: account, name: policy_name) do |p| + p.description = 'Migrated from inbox settings' + end + + inboxes_with_limit.each do |inbox| + next if InboxCapacityLimit.exists?(agent_capacity_policy_id: policy.id, inbox_id: inbox.id) + + limit = [inbox.auto_assignment_config['max_assignment_limit'].to_i, int_max].min + InboxCapacityLimit.create!(agent_capacity_policy: policy, inbox: inbox, conversation_limit: limit) + end + + member_user_ids = InboxMember.where(inbox_id: inboxes_with_limit.select(:id)).distinct.pluck(:user_id) + account.account_users + .where(user_id: member_user_ids, agent_capacity_policy_id: nil) + .find_each { |au| au.update!(agent_capacity_policy_id: policy.id) } + end + + migrated += 1 + puts " [#{migrated + skipped + errored}/#{total}] Account #{account.id} — migrated" + rescue StandardError => e + errored += 1 + puts " [#{migrated + skipped + errored}/#{total}] Account #{account.id} — error: #{e.message}" + end + + puts "\nDone! Migrated: #{migrated}, Skipped: #{skipped}, Errored: #{errored}, Total: #{total}" + end +end +# rubocop:enable Metrics/BlockLength