Backport of Sign chat agent requests from the chat feature setting and Sign chat tool requests from the resolved feature setting to 19.2

What does this MR do and why?

Backports the combination of !254156 (merged) and !256656 (merged) to fix #621674 (closed).

Also backported to %19.3 !257903 (merged), %19.4 !257901 (merged)

#621674 (closed) identified an issue where GitLab Duo self-hosted Duo Enterprise with offline licenses instances could not @ mention GitLabDuo in comments. This was fixed in two locations !254156 (merged) and !256656 (merged) for non-tool call, and tool call responses. These fixes are now being backported to %19.2, %19.3, %19.4

How to set up and validate locally

Environment set up

Prerequisites:

  1. AIGW set up locally
  2. gitlab runner
  3. Self hosted model, or a provider API key (Anthropic)

Set up steps

GDK in self-managed mode
  1. In gdk.yml: env: GITLAB_SIMULATE_SAAS: "0"
  2. Make sure CLOUD_CONNECTOR_SELF_SIGN_TOKENS appears in neither gdk.yml env: nor env.runit.
AI Gateway auth

In gitlab-ai-gateway/.env:

  • AIGW_CUSTOM_MODELS__ENABLED=true
  • AIGW_GITLAB_URL=http://:3000
  • AIGW_AUTH__BYPASS_EXTERNAL — unset or false
  • AIGW_AUTH__BYPASS_JWT_SIGNATURE — unset/false
  • AIGW_LOGGING__ENABLE_REQUEST_LOGGING=true — needed for the auth_error_details / token_issuer lines

gdk restart

License + add-ons (Duo Enterprise, no Agent Platform)

From the gitlab dir.

DEVELOPMENT_AI_GATEWAY_URL=http://localhost:5052 bundle exec rake "gitlab:duo:setup[duo_enterprise]"

bundle exec rake gitlab:duo:seed_self_hosted_models

Model set up

Option 1. Using Anthropic (recommended)

In http://gdk.test:8080/admin/gitlab_duo/model_selection/models/new use the following variables

Field

Click to sort ascending

Value

Click to sort ascending

Name

anthropic-opus-5 - self hosted - pointing to API - Or any other name

Platform API
Family Claude
Ednpoint

https://api.anthropic.com

Identifier anthropic/claude-opus-5
API key

your sk-ant-... key

Option 2. Locally running self hosted (not recommended)

I was also able to test this with a ollama-qwen25-7b (Llama 3) model.

Ollama set up and issues It required the following diff
kaveh@kvejad--20251026-73SB4:~/gdk/gitlab-ai-gateway$ git diff
diff --git a/ai_gateway/prompts/definitions/chat/merge_request_reader/llama3/1.0.0.yml b/ai_gateway/prompts/definitions/chat/merge_request_reader/llama3/1.0.0.yml
index 5b8d5c903c..dc6d2900db 100644
--- a/ai_gateway/prompts/definitions/chat/merge_request_reader/llama3/1.0.0.yml
+++ b/ai_gateway/prompts/definitions/chat/merge_request_reader/llama3/1.0.0.yml
@@ -14,3 +14,5 @@ prompt_template:
     {% include 'chat/merge_request_reader/assistant/1.0.0.jinja' %}
 params:
   timeout: 60
+  stop:
+    - "```"
diff --git a/ai_gateway/prompts/definitions/chat/react/llama3/1.0.0.yml b/ai_gateway/prompts/definitions/chat/react/llama3/1.0.0.yml
index d0fa4abeca..409d486dd5 100644
--- a/ai_gateway/prompts/definitions/chat/react/llama3/1.0.0.yml
+++ b/ai_gateway/prompts/definitions/chat/react/llama3/1.0.0.yml
@@ -13,6 +13,6 @@ prompt_template:
   assistant: |
     {% include 'chat/react/assistant/1.0.0.jinja' %}
 params:
-  timeout: 30
+  timeout: 200
   stop:
     - "Observation:"
  1. Follow https://docs.gitlab.com/development/ai_features/local_models/ set up steps
  2. Update http://gdk.test:8080/admin/gitlab_duo/model_selection/models/new with the new model

Main issues are:

  1. It is very slow
  2. It cannot handle much context, and is likely to fail for other reasons
Feature settings

At /admin/gitlab_duo/model_selection:

  • Assign a self-hosted model to General Chat (duo_chat feature) and Code Review (review_merge_request), and Code Review Summary.
  • Leave Agentic Chat (duo_agent_platform_agentic_chat) on the vendored default. That gap is exactly what stops :duo_chat from self-signing.
Simulate the air-gap (no CustomersDot token)

gdk rails c

CloudConnector::ServiceAccessToken.delete_all
CloudConnector::Tokens.cloud_connector_token.present? # => false
Force the non-agentic mention path

gdk rails c

gitlab:duo:setup enables all foundational flows, which routes mentions to the DAP handlers instead of the buggy chat path. On the test group/project, disable the code_review/v1 foundational flow (or duo_foundational_flows_enabled), then confirm:

project = Project.find_by_full_path('gitlab-duo/test')
user = User.find_by_username('root')

project.project_setting.update!(duo_foundational_flows_enabled: false)

Gitlab::Duo::CodeReview::ModeResolver.new(user: user, container: project).mode # => :classic
Verify preconditions, then reproduce
Ai::FeatureSetting.feature_for_unit_primitive(:duo_classic_chat)&.self_hosted? # => true 
Ai::FeatureSetting.feature_for_unit_primitive(:duo_chat)&.self_hosted? # => nil/false ← bug trigger 
CloudConnector::Tokens.get(unit_primitive: :duo_chat, resource: :instance) # => nil
CloudConnector::Tokens.get(unit_primitive: :duo_classic_chat, resource: :instance) # => JWT
Disable comment temperature and ai_prompts_v2
Feature.disable(:comment_temperature)
Feature.disable(:ai_prompts_v2) # https://gitlab.slack.com/archives/C06LWENL58F/p1789476326057429

Test

  1. Assign GitLabDuo as a reviewer of an MR
    1. Confirm Duo is able to review the MR
  2. Tag Duo in a comment that requires any tool usage
    1. @GitlabDuo give me a summary of this MR
  3. Tag Duo in a comment that does not require any tool usage
    1. @GitlabDuo Reply with "123" and do not use any tools
  4. Without the changes in this MR, the request should fail, with the change, you should see a response.
  5. Reset the gdk and env settings
    1. Undo changes in the two files
    2. gdk reconfigure gdk restart
    3. Retry command and confirm it still passes (we didn't break the other set ups)
  6. Update /admin/gitlab_duo/model_selection to point to a non self managed model
    1. Retry command and confirm it still passes (we didn't break the other set ups)

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

  • This MR is backporting a bug fix, documentation update, or spec fix, previously merged in the default branch.
  • The MR that fixed the bug on the default branch has been deployed to GitLab.com (not applicable for documentation or spec changes).
  • The MR title is descriptive (e.g. "Backport of 'title of default branch MR'"). This is important, since the title will be copied to the patch blog post.
  • Required labels have been applied to this merge request
  • This MR has been approved by a maintainer (only one approval is required).
  • Ensure the E2E Omnibus GitLab EE pipeline (triggered by thee2e:test-on-omnibus-ee job) has succeeded. If it has failed (or shows warnings), investigate the failures. If you determine the failures are unrelated, you may proceed. If you need assistance investigating, request help in the #s_developer_experience Slack channel to confirm the failures are unrelated to the merge request.

Note to the merge request author and maintainer

If you have questions about the patch release process, please:

Edited by Eugenia Grieff

Merge request reports

Loading
Loading