diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 0ad8a08960ae07d008c3369abb59947b27f503a3..a326fa308adc48d59bb0141ae3bc618e221b0ed5 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -12,6 +12,7 @@ module IssuableActions
     before_action :authorize_destroy_issuable!, only: :destroy
     before_action :check_destroy_confirmation!, only: :destroy
     before_action :authorize_admin_issuable!, only: :bulk_update
+    before_action :set_application_context!, only: :show
   end
 
   def show
@@ -226,6 +227,10 @@ def authorize_update_issuable!
     render_404 unless can?(current_user, :"update_#{resource_name}", issuable)
   end
 
+  def set_application_context!
+    # no-op. The logic is defined in EE module.
+  end
+
   def bulk_update_params
     clean_bulk_update_params(
       params.require(:update).permit(bulk_update_permitted_keys)
diff --git a/app/controllers/projects/merge_requests/conflicts_controller.rb b/app/controllers/projects/merge_requests/conflicts_controller.rb
index 6fd9eae9edba706e82bfd2f4c9f89e92f02100c9..66a358963e2388dbc49bfe255fd9941759d47e3f 100644
--- a/app/controllers/projects/merge_requests/conflicts_controller.rb
+++ b/app/controllers/projects/merge_requests/conflicts_controller.rb
@@ -75,6 +75,8 @@ def resolve_conflicts
 
   private
 
+  alias_method :issuable, :merge_request
+
   def authorize_can_resolve_conflicts!
     @conflicts_list = ::MergeRequests::Conflicts::ListService.new(@merge_request)
 
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 69f7d3f0ff59c4ec93987be239a6374d9f5a4741..c0dcdb01d48dd389a12391817da99ca4e0cbee46 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1045,6 +1045,7 @@ Input type: `AdminSidekiqQueuesDeleteJobsInput`
 
 | Name | Type | Description |
 | ---- | ---- | ----------- |
+| <a id="mutationadminsidekiqqueuesdeletejobsairesource"></a>`aiResource` | [`String`](#string) | Delete jobs matching ai_resource in the context metadata. |
 | <a id="mutationadminsidekiqqueuesdeletejobsartifactsize"></a>`artifactSize` | [`String`](#string) | Delete jobs matching artifact_size in the context metadata. |
 | <a id="mutationadminsidekiqqueuesdeletejobsartifactusedcdn"></a>`artifactUsedCdn` | [`String`](#string) | Delete jobs matching artifact_used_cdn in the context metadata. |
 | <a id="mutationadminsidekiqqueuesdeletejobsartifactsdependenciescount"></a>`artifactsDependenciesCount` | [`String`](#string) | Delete jobs matching artifacts_dependencies_count in the context metadata. |
diff --git a/ee/app/controllers/concerns/ee/issuable_actions.rb b/ee/app/controllers/concerns/ee/issuable_actions.rb
index 83b899353c20858ec774f3b97979c129cd920d90..e307ceef64f526577330f5c0286d63b6069d3dc3 100644
--- a/ee/app/controllers/concerns/ee/issuable_actions.rb
+++ b/ee/app/controllers/concerns/ee/issuable_actions.rb
@@ -18,5 +18,10 @@ module IssuableActions
     def bulk_update_permitted_keys
       @permitted_keys ||= (super + EE_PERMITTED_KEYS).freeze
     end
+
+    override :set_application_context!
+    def set_application_context!
+      ::Gitlab::ApplicationContext.push(ai_resource: issuable.try(:to_global_id))
+    end
   end
 end
diff --git a/ee/app/controllers/ee/projects/issues_controller.rb b/ee/app/controllers/ee/projects/issues_controller.rb
index 38dc727837666985ec6ef3fecd7390667f6a484d..916369300ad4c51f9b228141f4fda14d4d7de9d6 100644
--- a/ee/app/controllers/ee/projects/issues_controller.rb
+++ b/ee/app/controllers/ee/projects/issues_controller.rb
@@ -21,9 +21,7 @@ module IssuesController
         before_action only: :show do
           push_licensed_feature(:escalation_policies, project)
           push_force_frontend_feature_flag(:summarize_comments, can?(current_user, :summarize_notes, issue))
-          push_force_frontend_feature_flag(:generate_description_ai,
-            can?(current_user, :generate_description, issue))
-          @ai_resource_id = issue.to_global_id
+          push_force_frontend_feature_flag(:generate_description_ai, can?(current_user, :generate_description, issue))
         end
 
         before_action :redirect_if_test_case, only: [:show]
diff --git a/ee/app/views/layouts/_tanuki_bot_chat.html.haml b/ee/app/views/layouts/_tanuki_bot_chat.html.haml
index 26ec492b903121d718bd79508158329c22d9801b..fc55f95c1b4534ee6c465b4040fcc1b9e1e73d44 100644
--- a/ee/app/views/layouts/_tanuki_bot_chat.html.haml
+++ b/ee/app/views/layouts/_tanuki_bot_chat.html.haml
@@ -1,3 +1,4 @@
 - return unless ::Gitlab::Llm::TanukiBot.enabled_for?(user: current_user)
+- resource_id = Gitlab::ApplicationContext.current_context_attribute(:ai_resource).presence
 
-#js-tanuki-bot-chat-app{ data: { user_id: current_user.to_global_id, resource_id: @ai_resource_id } }
+#js-tanuki-bot-chat-app{ data: { user_id: current_user.to_global_id, resource_id: resource_id } }
diff --git a/ee/lib/ee/gitlab/application_context.rb b/ee/lib/ee/gitlab/application_context.rb
index 0f2027c64dd9f40da6271b23f23e74d3c6bfbba8..ec7c3ae9dbcca99f2c7f7145c2f2e4d915ebdc12 100644
--- a/ee/lib/ee/gitlab/application_context.rb
+++ b/ee/lib/ee/gitlab/application_context.rb
@@ -6,8 +6,15 @@ module ApplicationContext
       extend ::Gitlab::Utils::Override
       extend ActiveSupport::Concern
 
+      Attribute = Struct.new(:name, :type)
+
       EE_KNOWN_KEYS = [
-        :subscription_plan
+        :subscription_plan,
+        :ai_resource
+      ].freeze
+
+      EE_APPLICATION_ATTRIBUTES = [
+        Attribute.new(:ai_resource, ::GlobalID)
       ].freeze
 
       class_methods do
@@ -17,11 +24,18 @@ module ApplicationContext
         def known_keys
           super + EE_KNOWN_KEYS
         end
+
+        override :application_attributes
+        def application_attributes
+          super + EE_APPLICATION_ATTRIBUTES
+        end
       end
 
       override :to_lazy_hash
       def to_lazy_hash
         super.tap do |hash|
+          assign_hash_if_value(hash, :ai_resource)
+
           hash[:subscription_plan] = -> { subcription_plan_name } if include_namespace?
         end
       end
diff --git a/ee/spec/lib/ee/gitlab/application_context_spec.rb b/ee/spec/lib/ee/gitlab/application_context_spec.rb
index dc7f27b1427d6ac105ca629b5eb4cb5d1e65569e..d3a783fba9891a45bc773a5afa2f13c697e4b624 100644
--- a/ee/spec/lib/ee/gitlab/application_context_spec.rb
+++ b/ee/spec/lib/ee/gitlab/application_context_spec.rb
@@ -50,6 +50,7 @@ def result(context)
       [:remote_ip]                  | [:remote_ip, :client_id]
       [:runner]                     | [:project, :root_namespace, :client_id, :subscription_plan]
       [:caller_id]                  | [:caller_id]
+      [:ai_resource]                | [:ai_resource]
       []                            | []
     end
 
diff --git a/ee/spec/requests/projects/issues_controller_spec.rb b/ee/spec/requests/projects/issues_controller_spec.rb
index c941514b781d0294b3135b07e9b5d454e7ee9564..82919fa9b75483918e9f504db1f02cb915ebe07c 100644
--- a/ee/spec/requests/projects/issues_controller_spec.rb
+++ b/ee/spec/requests/projects/issues_controller_spec.rb
@@ -115,12 +115,6 @@ def get_show
         end
       end
     end
-
-    it 'assigns ai_resource_id' do
-      get_show
-
-      expect(assigns(:ai_resource_id)).to eq(issue.to_global_id)
-    end
   end
 
   describe 'GET #index' do
diff --git a/lib/gitlab/application_context.rb b/lib/gitlab/application_context.rb
index 0ea52b7b7c8213dd519626f74fa0b50336d238ae..67fc2ae2fcc0d37e4c932299746afd4d61d0d540 100644
--- a/lib/gitlab/application_context.rb
+++ b/lib/gitlab/application_context.rb
@@ -47,11 +47,16 @@ class ApplicationContext
       Attribute.new(:root_caller_id, String),
       Attribute.new(:merge_action_status, String)
     ].freeze
+    private_constant :APPLICATION_ATTRIBUTES
 
     def self.known_keys
       KNOWN_KEYS
     end
 
+    def self.application_attributes
+      APPLICATION_ATTRIBUTES
+    end
+
     def self.with_context(args, &block)
       application_context = new(**args)
       application_context.use(&block)
@@ -79,12 +84,13 @@ def self.current_context_attribute(attribute_name)
     end
 
     def initialize(**args)
-      unknown_attributes = args.keys - APPLICATION_ATTRIBUTES.map(&:name)
+      unknown_attributes = args.keys - self.class.application_attributes.map(&:name)
       raise ArgumentError, "#{unknown_attributes} are not known keys" if unknown_attributes.any?
 
       @set_values = args.keys
 
       assign_attributes(args)
+      set_attr_readers
     end
 
     # rubocop: disable Metrics/CyclomaticComplexity
@@ -122,12 +128,14 @@ def use
 
     attr_reader :set_values
 
-    APPLICATION_ATTRIBUTES.each do |attr|
-      lazy_attr_reader attr.name, type: attr.type
+    def set_attr_readers
+      self.class.application_attributes.each do |attr|
+        self.class.lazy_attr_reader attr.name, type: attr.type
+      end
     end
 
     def assign_hash_if_value(hash, attribute_name)
-      unless KNOWN_KEYS.include?(attribute_name)
+      unless self.class.known_keys.include?(attribute_name)
         raise ArgumentError, "unknown attribute `#{attribute_name}`"
       end
 
@@ -137,7 +145,7 @@ def assign_hash_if_value(hash, attribute_name)
     end
 
     def assign_attributes(values)
-      values.slice(*APPLICATION_ATTRIBUTES.map(&:name)).each do |name, value|
+      values.slice(*self.class.application_attributes.map(&:name)).each do |name, value|
         instance_variable_set("@#{name}", value)
       end
     end