Connect Resolve Vulnerability with AI Response
What does this MR do and why?
When the Resolve with AI is clicked, it loads the AI response. When the MR link is returned, it will redirect the user to the newly created MR.
MR | Changes |
---|---|
!136716 (merged) | Introduce the "Resolve with AI" UI button |
This MR | Handle onClick of the "Resolve with AI" button |
Screenshots or screen recordings
resolve-vulnerability-persisting-loading
How to set up and validate locally
- Have the related FF enabled:
echo "Feature.enable(:resolve_vulnerability_ai)" | rails c
- In order to run a pipeline to generate a Vulnerability report, you'll need an EE license.
- Fork https://gitlab.com/gitlab-org/security-products/tests/webgoat.net (for the solo button)
- Fork https://gitlab.com/gitlab-examples/security/security-reports (no button)
- Run a pipeline against the default branch. It will generate vulnerabilities.
- Go to the project vulnerability report page
- Click on the SAST vulnerability
- You will see the "Resolve with AI" button
- When clicked, it will load the the AI request, and when the response returns, it will redirect to the MR
Note: The API has changed a bit (Update resolve vulnerability to return MR link (!137384 - merged)), please apply this patch: MR has been merged and I have rebased
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137384/diffs.patch
Patch Code
From 7ac1d005e466f239f9182e0274fc76eef510c890 Mon Sep 17 00:00:00 2001
From: Samantha Ming <sming@gitlab.com>
Date: Mon, 20 Nov 2023 10:16:39 +0100
Subject: [PATCH 1/2] Update resolve vulnerability to return MR link
Update the response to return the MR link instead of the MR reference
---
ee/lib/gitlab/llm/completions/resolve_vulnerability.rb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb b/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb
index 06eb9e0dc2c0fb..93e63c25659c71 100644
--- a/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb
+++ b/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb
@@ -65,7 +65,8 @@ def create_merge_request(user, vulnerability, response)
return formatted_error_response(RESOLUTION_FAILURE_ERROR, context: result) unless result[:status] == :success
- { merge_request_reference: result[:merge_request].to_reference }
+ mr = result[:merge_request]
+ { merge_request_reference: Gitlab::Routing.url_helpers.project_merge_request_url(mr.project, mr) }
end
def error_message(error)
--
GitLab
From 251b8958af1a1bf521e322776e6fba07e06a408c Mon Sep 17 00:00:00 2001
From: Gregory <11164960-ghavenga@users.noreply.gitlab.com>
Date: Mon, 20 Nov 2023 13:22:31 +0200
Subject: [PATCH 2/2] Change RTV MR reference to the url
Changelog: changed
EE: true
---
.../llm/completions/resolve_vulnerability.rb | 2 +-
.../response_modifiers/resolve_vulnerability.rb | 6 +++---
.../completions/resolve_vulnerability_spec.rb | 4 ++--
.../resolve_vulnerability_spec.rb | 16 ++++++++--------
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb b/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb
index 93e63c25659c71..e48ca16f7e265e 100644
--- a/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb
+++ b/ee/lib/gitlab/llm/completions/resolve_vulnerability.rb
@@ -66,7 +66,7 @@ def create_merge_request(user, vulnerability, response)
return formatted_error_response(RESOLUTION_FAILURE_ERROR, context: result) unless result[:status] == :success
mr = result[:merge_request]
- { merge_request_reference: Gitlab::Routing.url_helpers.project_merge_request_url(mr.project, mr) }
+ { merge_request_url: Gitlab::Routing.url_helpers.project_merge_request_url(mr.project, mr) }
end
def error_message(error)
diff --git a/ee/lib/gitlab/llm/response_modifiers/resolve_vulnerability.rb b/ee/lib/gitlab/llm/response_modifiers/resolve_vulnerability.rb
index abe7e7fdab43b3..301b295a26a625 100644
--- a/ee/lib/gitlab/llm/response_modifiers/resolve_vulnerability.rb
+++ b/ee/lib/gitlab/llm/response_modifiers/resolve_vulnerability.rb
@@ -7,7 +7,7 @@ class ResolveVulnerability < ::Gitlab::Llm::BaseResponseModifier
include Gitlab::Utils::StrongMemoize
def response_body
- @response_body ||= ai_response&.dig(:merge_request_reference).to_s
+ @response_body ||= ai_response&.dig(:merge_request_url).to_s
end
strong_memoize_attr :response_body
@@ -21,8 +21,8 @@ def empty_response_error
case ai_response
when {}, nil
"The response from the AI provider was empty."
- when { 'merge_request_reference' => nil }
- "No resolution merge request reference was provided"
+ when { 'merge_request_url' => nil }
+ "No resolution merge request url was provided"
end
end
end
diff --git a/ee/spec/lib/gitlab/llm/completions/resolve_vulnerability_spec.rb b/ee/spec/lib/gitlab/llm/completions/resolve_vulnerability_spec.rb
index 971ea5f83408fc..671953617fe075 100644
--- a/ee/spec/lib/gitlab/llm/completions/resolve_vulnerability_spec.rb
+++ b/ee/spec/lib/gitlab/llm/completions/resolve_vulnerability_spec.rb
@@ -8,7 +8,7 @@
let(:prompt_class) { Gitlab::Llm::Templates::Vulnerabilities::ResolveVulnerability }
let(:merge_request_service) { ::MergeRequests::CreateFromVulnerabilityDataService }
let(:merge_request) { create(:merge_request, source_project: project) }
- let(:mr_reference) { merge_request.to_reference }
+ let(:mr_url) { Gitlab::Routing.url_helpers.project_merge_request_url(project, merge_request) }
let(:code_patch) { "somecode\nexecute" }
let(:example_response) do
{
@@ -128,7 +128,7 @@ def execute_resolve(message_params = {}, options = {})
expect(GraphqlTriggers).to have_received(:ai_completion_response).with(
an_object_having_attributes(
- content: mr_reference,
+ content: mr_url,
role: ::Gitlab::Llm::AiMessage::ROLE_ASSISTANT,
request_id: 'uuid',
errors: [],
diff --git a/ee/spec/lib/gitlab/llm/response_modifiers/resolve_vulnerability_spec.rb b/ee/spec/lib/gitlab/llm/response_modifiers/resolve_vulnerability_spec.rb
index 1456efc2d1485e..636ccd97e5e1d3 100644
--- a/ee/spec/lib/gitlab/llm/response_modifiers/resolve_vulnerability_spec.rb
+++ b/ee/spec/lib/gitlab/llm/response_modifiers/resolve_vulnerability_spec.rb
@@ -27,25 +27,25 @@
it_behaves_like 'empty response error'
end
- context 'when no merge request reference is passed' do
- let(:reference) { nil }
- let(:ai_response) { { 'merge_request_reference' => reference }.to_json }
+ context 'when no merge request url is passed' do
+ let(:url) { nil }
+ let(:ai_response) { { 'merge_request_url' => url }.to_json }
it 'parses content from the ai response' do
expect(response_modifier.response_body).to eq('')
end
it 'returns empty errors' do
- expect(response_modifier.errors).to match_array("No resolution merge request reference was provided")
+ expect(response_modifier.errors).to match_array("No resolution merge request url was provided")
end
end
- context 'when a merge request reference is passed' do
- let(:reference) { "!1" }
- let(:ai_response) { { 'merge_request_reference' => reference }.to_json }
+ context 'when a merge request url is passed' do
+ let(:url) { "http://localhost/namespace1/project-1/-/merge_requests/1" }
+ let(:ai_response) { { 'merge_request_url' => url }.to_json }
it 'parses content from the ai response' do
- expect(response_modifier.response_body).to eq(reference)
+ expect(response_modifier.response_body).to eq(url)
end
it 'returns empty errors' do
--
GitLab
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #430888 (closed)
Edited by Samantha Ming