From 950670e94d899e5e3c64c2d24797ad77cac113ab Mon Sep 17 00:00:00 2001 From: Igor Drozdov Date: Mon, 18 Aug 2025 10:51:28 +0200 Subject: [PATCH] Enable web chat for Duo Core --- .../components/duo_core_features_form.vue | 4 +- ee/lib/gitlab/llm/tanuki_bot.rb | 7 -- .../components/duo_core_features_form_spec.js | 4 +- ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb | 78 ++++--------------- locale/gitlab.pot | 4 +- 5 files changed, 19 insertions(+), 78 deletions(-) diff --git a/ee/app/assets/javascripts/ai/settings/components/duo_core_features_form.vue b/ee/app/assets/javascripts/ai/settings/components/duo_core_features_form.vue index f392bddf5d96e7..9bea39dc5a6307 100644 --- a/ee/app/assets/javascripts/ai/settings/components/duo_core_features_form.vue +++ b/ee/app/assets/javascripts/ai/settings/components/duo_core_features_form.vue @@ -16,9 +16,9 @@ export default { i18n: { sectionTitle: __('Gitlab Duo Core'), subtitle: s__( - 'AiPowered|When turned on, all billable users can access GitLab Duo Chat and Code Suggestions in supported IDEs.', + 'AiPowered|When turned on, all billable users can access GitLab Duo Chat and Code Suggestions in Web and supported IDEs.', ), - checkboxLabel: s__('AiPowered|Turn on IDE features'), + checkboxLabel: s__('AiPowered|Turn on Web and IDE features'), checkboxHelpTextSaaS: s__( 'AiPowered|This setting applies to the whole top-level group. By turning this on, you accept the %{termsLinkStart}GitLab AI Functionality Terms%{termsLinkEnd} unless your organization has a separate agreement with GitLab governing AI feature usage. Check the %{requirementsLinkStart}eligibility requirements%{requirementsLinkEnd}.', ), diff --git a/ee/lib/gitlab/llm/tanuki_bot.rb b/ee/lib/gitlab/llm/tanuki_bot.rb index cd973af849550d..d3054907cc83d2 100644 --- a/ee/lib/gitlab/llm/tanuki_bot.rb +++ b/ee/lib/gitlab/llm/tanuki_bot.rb @@ -5,7 +5,6 @@ module Llm class TanukiBot def self.enabled_for?(user:, container: nil) return false unless chat_enabled?(user) - return false if authorized_by_duo_core?(user) authorizer_response = if container Gitlab::Llm::Chain::Utils::ChatAuthorizer.container(container: container, user: user) @@ -30,16 +29,10 @@ def self.agentic_mode_available?(user:, project:, group:) def self.show_breadcrumbs_entry_point?(user:, container: nil) return false unless chat_enabled?(user) && container - return false if authorized_by_duo_core?(user) Gitlab::Llm::Chain::Utils::ChatAuthorizer.user(user: user).allowed? end - def self.authorized_by_duo_core?(user) - authorization_response = user.allowed_to_use(:duo_chat) - authorization_response.authorized_by_duo_core - end - def self.chat_disabled_reason(user:, container: nil) return unless container diff --git a/ee/spec/frontend/ai/settings/components/duo_core_features_form_spec.js b/ee/spec/frontend/ai/settings/components/duo_core_features_form_spec.js index 82a17906bf9ed3..68970394ea97b9 100644 --- a/ee/spec/frontend/ai/settings/components/duo_core_features_form_spec.js +++ b/ee/spec/frontend/ai/settings/components/duo_core_features_form_spec.js @@ -44,12 +44,12 @@ describe('DuoCoreFeaturesForm', () => { it('renders the subtitle', () => { expect(wrapper.text()).toMatch( - 'When turned on, all billable users can access GitLab Duo Chat and Code Suggestions in supported IDEs.', + 'When turned on, all billable users can access GitLab Duo Chat and Code Suggestions in Web and supported IDEs.', ); }); it('renders the checkbox with correct label', () => { - expect(findFormCheckbox().text()).toContain('Turn on IDE features'); + expect(findFormCheckbox().text()).toContain('Turn on Web and IDE features'); }); it('sets initial checkbox state based on duoCoreFeaturesEnabled prop when unselected', () => { diff --git a/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb b/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb index 3f8d45d1aff5ae..e406fa8436c64e 100644 --- a/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb +++ b/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb @@ -49,16 +49,6 @@ end end - context 'when user is authorized by duo core' do - before do - allow(described_class).to receive(:authorized_by_duo_core?).with(user).and_return(true) - end - - it 'returns false' do - expect(described_class.enabled_for?(user: user)).to be(false) - end - end - context 'when user is not present' do it 'returns false' do expect(described_class.enabled_for?(user: nil)).to be(false) @@ -185,28 +175,24 @@ before do allow(described_class).to receive(:chat_enabled?).with(user) .and_return(ai_features_enabled_for_user) - allow(described_class).to receive(:authorized_by_duo_core?).with(user).and_return(authorized_by_duo_core) allow(Gitlab::Llm::Chain::Utils::ChatAuthorizer).to receive(:user).with(user: user) .and_return(authorizer_response) end - where(:container, :ai_features_enabled_for_user, :allowed, :authorized_by_duo_core, :duo_chat_access) do + where(:container, :ai_features_enabled_for_user, :allowed, :duo_chat_access) do [ - [:project, true, true, false, true], - [:project, true, false, false, false], - [:project, false, false, false, false], - [:project, false, true, false, false], - [:project, true, true, true, false], - [:group, true, true, false, true], - [:group, true, false, false, false], - [:group, false, false, false, false], - [:group, false, true, false, false], - [:group, true, true, true, false], - [nil, true, true, false, false], - [nil, true, false, false, false], - [nil, false, false, false, false], - [nil, false, true, false, false], - [nil, true, true, true, false] + [:project, true, true, true], + [:project, true, false, false], + [:project, false, false, false], + [:project, false, true, false], + [:group, true, true, true], + [:group, true, false, false], + [:group, false, false, false], + [:group, false, true, false], + [nil, true, true, false], + [nil, true, false, false], + [nil, false, false, false], + [nil, false, true, false] ] end @@ -217,44 +203,6 @@ end end - describe '.authorized_by_duo_core?' do - let(:user_authorization_response) do - instance_double(Ai::UserAuthorizable::Response, allowed?: allowed, authorized_by_duo_core: authorized_by_duo_core) - end - - let(:authorized_by_duo_core) { false } - let(:allowed) { true } - - before do - allow(user).to receive(:allowed_to_use).with(:duo_chat).and_return(user_authorization_response) - end - - context 'when user is authorized by duo core' do - let(:authorized_by_duo_core) { true } - - it 'returns true' do - expect(described_class.authorized_by_duo_core?(user)).to be(true) - end - end - - context 'when user is not authorized by duo core' do - let(:authorized_by_duo_core) { false } - - it 'returns false' do - expect(described_class.authorized_by_duo_core?(user)).to be(false) - end - end - - context 'when allowed? is false' do - let(:allowed) { false } - let(:authorized_by_duo_core) { false } - - it 'returns false' do - expect(described_class.authorized_by_duo_core?(user)).to be(false) - end - end - end - describe '.chat_disabled_reason' do let(:authorizer_response) { instance_double(Gitlab::Llm::Utils::Authorizer::Response, allowed?: allowed) } let(:container) { build_stubbed(:group) } diff --git a/locale/gitlab.pot b/locale/gitlab.pot index efbf6a5c261572..172eee283a971f 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6391,7 +6391,7 @@ msgstr "" msgid "AiPowered|Turn on GitLab Duo Agent Platform" msgstr "" -msgid "AiPowered|Turn on IDE features" +msgid "AiPowered|Turn on Web and IDE features" msgstr "" msgid "AiPowered|Turn on experiment and beta GitLab Duo features" @@ -6424,7 +6424,7 @@ msgstr "" msgid "AiPowered|When GitLab Duo is not available, prompt caching cannot be turned on." msgstr "" -msgid "AiPowered|When turned on, all billable users can access GitLab Duo Chat and Code Suggestions in supported IDEs." +msgid "AiPowered|When turned on, all billable users can access GitLab Duo Chat and Code Suggestions in Web and supported IDEs." msgstr "" msgid "AiPowered|When you save, GitLab Duo will be turned off for all groups, subgroups, and projects." -- GitLab