Support Point-by-Point approach in comments
Enhanced comments to support a synthetic point-by-point approach,
mirroring the existing method used for Patchset reviews.
With this change, the stream output mode is always set to false for
comment inquiries, regardless of the `gptStreamOutput` config setting
value.
Jira-Id: IT-103
Change-Id: I319fa42887201ca74b9141b207fc094f112454a9
Signed-off-by: Patrizio <patrizio.gelosi@amarulasolutions.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
index 6b2918e..cb45a74 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
@@ -8,7 +8,7 @@
import com.googlesource.gerrit.plugins.chatgpt.client.GerritClient;
import com.googlesource.gerrit.plugins.chatgpt.client.InlineCode;
import com.googlesource.gerrit.plugins.chatgpt.client.OpenAiClient;
-import com.googlesource.gerrit.plugins.chatgpt.client.model.ChatGptSuggestion;
+import com.googlesource.gerrit.plugins.chatgpt.client.model.ChatGptSuggestionPoint;
import com.googlesource.gerrit.plugins.chatgpt.client.model.GerritCommentRange;
import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
import lombok.extern.slf4j.Slf4j;
@@ -29,10 +29,9 @@
private final OpenAiClient openAiClient;
private List<HashMap<String, Object>> reviewBatches;
- private String currentTag;
private List<JsonObject> commentProperties;
private HashMap<String, List<String>> filesNewContent;
- private boolean isPatchSetEvent;
+ private boolean isCommentEvent;
@Inject
PatchSetReviewer(GerritClient gerritClient, OpenAiClient openAiClient) {
@@ -52,7 +51,7 @@
String reviewSuggestion = getReviewSuggestion(config, fullChangeId, patchSet);
log.info("ChatGPT response: {}", reviewSuggestion);
- if (isPatchSetEvent && config.getGptReviewByPoints()) {
+ if (isCommentEvent || config.getGptReviewByPoints()) {
retrieveReviewFromJson(reviewSuggestion);
}
else {
@@ -62,11 +61,11 @@
gerritClient.postComments(fullChangeId, reviewBatches);
}
- public void setIsPatchSetEvent(boolean isPatchSetEvent) {
- this.isPatchSetEvent = isPatchSetEvent;
+ public void setIsCommentEvent(boolean isCommentEvent) {
+ this.isCommentEvent = isCommentEvent;
}
- private Integer getBatchId() {
+ private Integer getBatchId(String currentTag) {
try {
return Integer.parseInt(currentTag);
}
@@ -75,14 +74,9 @@
}
}
- private void addReviewBatch(StringBuilder batch) {
+ private void addReviewBatch(Integer batchID, String batch) {
HashMap<String, Object> batchMap = new HashMap<>();
- batchMap.put("content", batch.toString());
- Integer batchID = getBatchId();
- if (batchID == null) {
- log.warn("Error retrieving batch ID from currentTag {}", currentTag);
- return;
- }
+ batchMap.put("content", batch);
if (commentProperties != null && batchID < commentProperties.size()) {
JsonObject commentProperty = commentProperties.get(batchID);
if (commentProperty != null &&
@@ -102,7 +96,7 @@
reviewBatches.add(batchMap);
}
- private Optional<GerritCommentRange> getGerritCommentRange(ChatGptSuggestion suggestion) {
+ private Optional<GerritCommentRange> getGerritCommentRange(ChatGptSuggestionPoint suggestion) {
Optional<GerritCommentRange> gerritCommentRange = Optional.empty();
if (suggestion.getFilename() == null) {
return gerritCommentRange;
@@ -125,40 +119,45 @@
private void retrieveReviewFromJson(String review) {
review = review.replaceAll("^`*(?:json)?\\s*|\\s*`+$", "");
- Type chatGptResponseListType = new TypeToken<List<ChatGptSuggestion>>(){}.getType();
- List<ChatGptSuggestion> reviewJson = gson.fromJson(review, chatGptResponseListType);
+ Type chatGptResponseListType = new TypeToken<List<ChatGptSuggestionPoint>>(){}.getType();
+ List<ChatGptSuggestionPoint> reviewJson = gson.fromJson(review, chatGptResponseListType);
filesNewContent = gerritClient.getFilesNewContent();
- for (ChatGptSuggestion suggestion : reviewJson) {
+ for (ChatGptSuggestionPoint suggestion : reviewJson) {
HashMap<String, Object> batchMap = new HashMap<>();
- batchMap.put("content", suggestion.getSuggestion());
- Optional<GerritCommentRange> optGerritCommentRange = getGerritCommentRange(suggestion);
- if (optGerritCommentRange.isPresent()) {
- GerritCommentRange gerritCommentRange = optGerritCommentRange.get();
- batchMap.put("filename", suggestion.getFilename());
- batchMap.put("line", gerritCommentRange.getStart_line());
- batchMap.put("range", gerritCommentRange);
+ if (suggestion.getId() != null) {
+ addReviewBatch(suggestion.getId(), suggestion.getSuggestion());
}
- reviewBatches.add(batchMap);
+ else {
+ batchMap.put("content", suggestion.getSuggestion());
+ Optional<GerritCommentRange> optGerritCommentRange = getGerritCommentRange(suggestion);
+ if (optGerritCommentRange.isPresent()) {
+ GerritCommentRange gerritCommentRange = optGerritCommentRange.get();
+ batchMap.put("filename", suggestion.getFilename());
+ batchMap.put("line", gerritCommentRange.getStart_line());
+ batchMap.put("range", gerritCommentRange);
+ }
+ reviewBatches.add(batchMap);
+ }
}
}
private void splitReviewIntoBatches(String review) {
String[] lines = review.split("\n");
- currentTag = "0";
+ Integer currentTag = 0;
StringBuilder batch = new StringBuilder();
for (int i = 0; i < lines.length; i++) {
String[] extractResult = extractID(lines[i]);
if (extractResult != null) {
log.debug("Captured '{}' from line '{}'", extractResult[0], lines[i]);
- addReviewBatch(batch);
+ addReviewBatch(currentTag, batch.toString());
batch = new StringBuilder();
- currentTag = extractResult[0];
+ currentTag = getBatchId(extractResult[0]);
lines[i] = extractResult[1];
}
batch.append(lines[i]).append("\n");
}
if (batch.length() > 0) {
- addReviewBatch(batch);
+ addReviewBatch(currentTag, batch.toString());
}
log.info("Review batches created: {}", reviewBatches.size());
log.debug("batches: {}", reviewBatches);
@@ -170,7 +169,7 @@
log.warn("Patch set too large. Skipping review. changeId: {}", changeId);
return String.format(SPLIT_REVIEW_MSG, config.getMaxReviewLines());
}
- return openAiClient.ask(config, patchSet);
+ return openAiClient.ask(config, patchSet, isCommentEvent);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientComments.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientComments.java
index 8ab3f5d..cf2a574 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientComments.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientComments.java
@@ -7,6 +7,7 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
+import com.googlesource.gerrit.plugins.chatgpt.client.model.ChatGptRequestPoint;
import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
@@ -148,22 +149,21 @@
return map;
}
- protected String getCommentPrompt(int i) {
- StringBuilder commentString = new StringBuilder();
+ protected ChatGptRequestPoint getRequestPoint(int i) {
+ ChatGptRequestPoint requestPoint = new ChatGptRequestPoint();
JsonObject commentProperty = commentProperties.get(i);
+ requestPoint.setId(i);
if (commentProperty.has("line") || commentProperty.has("range")) {
String filename = commentProperty.get("filename").getAsString();
InlineCode inlineCode = new InlineCode(filesNewContent.get(filename));
- commentString.append(String.format(Configuration.DEFAULT_GPT_CUSTOM_USER_CONTEXT_PROMPT,
- inlineCode.getInlineCode(commentProperty),
- commentProperty.get("line").getAsInt(),
- filename
- ));
+ requestPoint.setFilename(filename);
+ requestPoint.setLineNumber(commentProperty.get("line").getAsInt());
+ requestPoint.setCodeSnippet(inlineCode.getInlineCode(commentProperty));
}
String commentMessage = commentProperty.get("message").getAsString();
- commentString.append(removeMentionsFromComment(commentMessage).trim());
+ requestPoint.setRequest(removeMentionsFromComment(commentMessage).trim());
- return commentString.toString();
+ return requestPoint;
}
public List<JsonObject> getCommentProperties() {
@@ -216,11 +216,11 @@
public String getUserPrompt(HashMap<String, List<String>> filesNewContent) {
this.filesNewContent = filesNewContent;
- StringBuilder taggedPrompt = new StringBuilder();
+ List<ChatGptRequestPoint> requestPoints = new ArrayList<>();
for (int i = 0; i < commentProperties.size(); i++) {
- taggedPrompt.append(String.format("[ID:%d] %s\n", i, getCommentPrompt(i)));
+ requestPoints.add(getRequestPoint(i));
}
- return taggedPrompt.toString();
+ return requestPoints.isEmpty() ? "" : gson.toJson(requestPoints);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/InlineCode.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/InlineCode.java
index adba4e8..3d9123d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/InlineCode.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/InlineCode.java
@@ -2,7 +2,7 @@
import com.google.gson.JsonObject;
import com.google.gson.Gson;
-import com.googlesource.gerrit.plugins.chatgpt.client.model.ChatGptSuggestion;
+import com.googlesource.gerrit.plugins.chatgpt.client.model.ChatGptSuggestionPoint;
import com.googlesource.gerrit.plugins.chatgpt.client.model.GerritCommentRange;
import lombok.extern.slf4j.Slf4j;
@@ -49,7 +49,7 @@
return Math.abs((range.end_line - range.start_line) / 2 - fromLine);
}
- public Optional<GerritCommentRange> findCommentRange(ChatGptSuggestion suggestion) {
+ public Optional<GerritCommentRange> findCommentRange(ChatGptSuggestionPoint suggestion) {
int commentedLine;
try {
commentedLine = suggestion.getLineNumber();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/OpenAiClient.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/OpenAiClient.java
index cd2b52b..0f5183e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/OpenAiClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/OpenAiClient.java
@@ -28,6 +28,7 @@
.disableHtmlEscaping()
.create();
private final HttpClientWithRetry httpClientWithRetry = new HttpClientWithRetry();
+ private boolean isCommentEvent = false;
public String getRequestBody() {
return requestBody;
@@ -44,14 +45,18 @@
if (body == null) {
throw new IOException("ChatGPT response body is null");
}
- String content = extractContent(config, body);
- log.debug("ChatGPT response content: {}", content);
- return content;
+ return extractContent(config, body);
+ }
+
+ public String ask(Configuration config, String patchSet, boolean isCommentEvent) throws Exception {
+ this.isCommentEvent = isCommentEvent;
+
+ return this.ask(config, patchSet);
}
public String extractContent(Configuration config, String body) throws Exception {
- if (config.getGptStreamOutput()) {
+ if (config.getGptStreamOutput() && !isCommentEvent) {
StringBuilder finalContent = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new StringReader(body))) {
String line;
@@ -98,7 +103,7 @@
.model(config.getGptModel())
.messages(messages)
.temperature(config.getGptTemperature())
- .stream(config.getGptStreamOutput())
+ .stream(config.getGptStreamOutput() && !isCommentEvent)
.build();
return gson.toJson(chatCompletionRequest);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptPointBase.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptPointBase.java
new file mode 100644
index 0000000..375f457
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptPointBase.java
@@ -0,0 +1,11 @@
+package com.googlesource.gerrit.plugins.chatgpt.client.model;
+
+import lombok.Data;
+
+@Data
+public class ChatGptPointBase {
+ protected Integer id;
+ protected String filename;
+ protected Integer lineNumber;
+ protected String codeSnippet;
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptRequestPoint.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptRequestPoint.java
new file mode 100644
index 0000000..c202125
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptRequestPoint.java
@@ -0,0 +1,8 @@
+package com.googlesource.gerrit.plugins.chatgpt.client.model;
+
+import lombok.Data;
+
+@Data
+public class ChatGptRequestPoint extends ChatGptPointBase {
+ private String request;
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptSuggestion.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptSuggestion.java
deleted file mode 100644
index 3acc2f6..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptSuggestion.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.googlesource.gerrit.plugins.chatgpt.client.model;
-
-import lombok.Data;
-
-@Data
-public class ChatGptSuggestion {
- private String suggestion;
- private String filename;
- private Integer lineNumber;
- private String codeSnippet;
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptSuggestionPoint.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptSuggestionPoint.java
new file mode 100644
index 0000000..39c7e57
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/model/ChatGptSuggestionPoint.java
@@ -0,0 +1,8 @@
+package com.googlesource.gerrit.plugins.chatgpt.client.model;
+
+import lombok.Data;
+
+@Data
+public class ChatGptSuggestionPoint extends ChatGptPointBase {
+ private String suggestion;
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java
index 60d721d..51f82a6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/config/Configuration.java
@@ -25,20 +25,22 @@
public static final String DEFAULT_GPT_USER_PROMPT = "Focus your review on the \"a\" and \"b\" items, but use " +
"the \"ab\" items as context to understand the changes better. Provide insights on whether the changes " +
"make sense, any potential issues you foresee, and suggestions for improvements if necessary.";
- public static final String DEFAULT_GPT_USER_PROMPT_JSON = "Provide your feedback in a JSON format. Each " +
+ public static final String DEFAULT_GPT_USER_PROMPT_JSON = "Provide your response in a JSON format. Each " +
"suggestion must be formatted as an individual object within an array. The object will always contain " +
- "the key `suggestion`. For suggestions that are specific to a certain part of the code, the object " +
- "should additionally include the keys `filename`, `lineNumber`, and `codeSnippet` to precisely identify " +
- "the relevant code section.";
+ "the key `suggestion`";
+ public static final String DEFAULT_GPT_CUSTOM_USER_PROMPT_JSON = " along with the key `id`, which corresponds to " +
+ "the `id` value from the related request in the request JSON array";
+ public static final String DEFAULT_GPT_USER_PROMPT_JSON_2 = ". For suggestions that are specific to a certain " +
+ "part of the code, the object should additionally include the keys `filename`, `lineNumber`, and " +
+ "`codeSnippet` to precisely identify the relevant code section.";
public static final String DEFAULT_GPT_CUSTOM_USER_PROMPT_1 = "I have some requests about the following PatchSet " +
"Diff:";
- public static final String DEFAULT_GPT_CUSTOM_USER_PROMPT_2 = "Here are my requests:";
- public static final String DEFAULT_GPT_CUSTOM_USER_CONTEXT_PROMPT = "In reference to the code `%s` (from line %d " +
- "of file \"%s\"), ";
+ public static final String DEFAULT_GPT_CUSTOM_USER_PROMPT_2 = "My requests are given in an array and formatted " +
+ "in JSON :";
public static final String DEFAULT_GPT_COMMIT_MESSAGES_REVIEW_USER_PROMPT = "Also, perform a check on the commit " +
"message of the PatchSet. The commit message is provided in the \"content\" field of \"/COMMIT_MSG\" in " +
- "the same way as the file changes. Ensure that the commit message accurately and succinctly describes the " +
- "changes made, and verify if it matches the nature and scope of the changes in the PatchSet.";
+ "the same way as the file changes. Ensure that the commit message accurately and succinctly describes " +
+ "the changes made, and verify if it matches the nature and scope of the changes in the PatchSet.";
public static final String NOT_CONFIGURED_ERROR_MSG = "%s is not configured";
public static final String KEY_GPT_SYSTEM_PROMPT = "gptSystemPrompt";
public static final String KEY_GPT_USER_PROMPT = "gptUserPrompt";
@@ -169,13 +171,14 @@
DEFAULT_GPT_CUSTOM_USER_PROMPT_1,
patchSet,
DEFAULT_GPT_CUSTOM_USER_PROMPT_2,
- gptUserPrompt
+ gptUserPrompt,
+ DEFAULT_GPT_USER_PROMPT_JSON + DEFAULT_GPT_CUSTOM_USER_PROMPT_JSON + DEFAULT_GPT_USER_PROMPT_JSON_2
));
}
else {
prompt.add(getString(KEY_GPT_USER_PROMPT, DEFAULT_GPT_USER_PROMPT));
if (getGptReviewByPoints()) {
- prompt.add(DEFAULT_GPT_USER_PROMPT_JSON);
+ prompt.add(DEFAULT_GPT_USER_PROMPT_JSON + DEFAULT_GPT_USER_PROMPT_JSON_2);
}
if (getGptReviewCommitMessages()) {
prompt.add(DEFAULT_GPT_COMMIT_MESSAGES_REVIEW_USER_PROMPT);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java
index 9e80650..df12b59 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java
@@ -149,14 +149,14 @@
if (!isPatchSetReviewEnabled(patchSetEvent)) {
return;
}
- reviewer.setIsPatchSetEvent(true);
+ reviewer.setIsCommentEvent(false);
break;
case "comment-added":
if (!gerritClient.retrieveLastComments(event, fullChangeId)) {
log.info("No comments found for review");
return;
}
- reviewer.setIsPatchSetEvent(false);
+ reviewer.setIsCommentEvent(true);
break;
default:
return;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
index 294a9a8..bf2553f 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
@@ -72,8 +72,8 @@
private static final BranchNameKey BRANCH_NAME = BranchNameKey.create(PROJECT_NAME, "myBranchName");
private static final boolean GPT_STREAM_OUTPUT = true;
private static final long TEST_TIMESTAMP = 1699270812;
- private static final String REVIEW_TAG_COMMENTS = "[ID:0] comment 2\n" +
- "[ID:1] In reference to the code `TypeClassOrPath` (from line 5 of file \"test_file.py\"), message\n";
+ private static final String REVIEW_TAG_COMMENTS = "[{\"request\":\"comment 2\",\"id\":0},{\"request\":" +
+ "\"message\",\"id\":1,\"filename\":\"test_file.py\",\"lineNumber\":5,\"codeSnippet\":\"TypeClassOrPath\"}]";
private final Gson gson = new Gson();
@@ -209,7 +209,7 @@
));
reviewUserPromptByPoints = String.join("\n", Arrays.asList(
Configuration.DEFAULT_GPT_USER_PROMPT,
- Configuration.DEFAULT_GPT_USER_PROMPT_JSON,
+ Configuration.DEFAULT_GPT_USER_PROMPT_JSON + Configuration.DEFAULT_GPT_USER_PROMPT_JSON_2,
Configuration.DEFAULT_GPT_COMMIT_MESSAGES_REVIEW_USER_PROMPT,
diffContent
));
@@ -217,7 +217,9 @@
Configuration.DEFAULT_GPT_CUSTOM_USER_PROMPT_1,
diffContent,
Configuration.DEFAULT_GPT_CUSTOM_USER_PROMPT_2,
- REVIEW_TAG_COMMENTS
+ REVIEW_TAG_COMMENTS,
+ Configuration.DEFAULT_GPT_USER_PROMPT_JSON + Configuration.DEFAULT_GPT_CUSTOM_USER_PROMPT_JSON +
+ Configuration.DEFAULT_GPT_USER_PROMPT_JSON_2
));
}
@@ -285,6 +287,12 @@
PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient, openAiClient);
ConfigCreator mockConfigCreator = mock(ConfigCreator.class);
when(mockConfigCreator.createConfig(ArgumentMatchers.any())).thenReturn(config);
+ WireMock.stubFor(WireMock.post(WireMock.urlEqualTo(URI.create(config.getGptDomain()
+ + UriResourceLocator.chatCompletionsUri()).getPath()))
+ .willReturn(WireMock.aResponse()
+ .withStatus(HTTP_OK)
+ .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
+ .withBodyFile("chatGptResponseByPoints.json")));
PatchSetCreatedEvent event = mock(PatchSetCreatedEvent.class);
when(event.getProjectNameKey()).thenReturn(PROJECT_NAME);
@@ -294,13 +302,6 @@
event.patchSet = this::createPatchSetAttribute;
EventListenerHandler eventListenerHandler = new EventListenerHandler(patchSetReviewer, gerritClient);
- WireMock.stubFor(WireMock.post(WireMock.urlEqualTo(URI.create(config.getGptDomain()
- + UriResourceLocator.chatCompletionsUri()).getPath()))
- .willReturn(WireMock.aResponse()
- .withStatus(HTTP_OK)
- .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
- .withBodyFile("chatGptResponseByPoints.json")));
-
GerritListener gerritListener = new GerritListener(mockConfigCreator, eventListenerHandler);
gerritListener.onEvent(event);
CompletableFuture<Void> future = eventListenerHandler.getLatestFuture();
@@ -354,6 +355,12 @@
ConfigCreator mockConfigCreator = mock(ConfigCreator.class);
when(config.getGerritUserName()).thenReturn("gpt");
when(mockConfigCreator.createConfig(ArgumentMatchers.any())).thenReturn(config);
+ WireMock.stubFor(WireMock.post(WireMock.urlEqualTo(URI.create(config.getGptDomain()
+ + UriResourceLocator.chatCompletionsUri()).getPath()))
+ .willReturn(WireMock.aResponse()
+ .withStatus(HTTP_OK)
+ .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
+ .withBodyFile("chatGptResponseCommentsByPoints.json")));
CommentAddedEvent event = mock(CommentAddedEvent.class);
when(event.getProjectNameKey()).thenReturn(PROJECT_NAME);
diff --git a/src/test/resources/__files/chatGptResponseCommentsByPoints.json b/src/test/resources/__files/chatGptResponseCommentsByPoints.json
new file mode 100644
index 0000000..7b69870
--- /dev/null
+++ b/src/test/resources/__files/chatGptResponseCommentsByPoints.json
@@ -0,0 +1,11 @@
+{
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "```json\n[\n {\n \"id\": 0,\n \"suggestion\": \"The commit message 'Test Commit Message' is too vague and does not provide information about the specific changes made. A more detailed message is necessary to understand what has been fixed.\"\n },\n {\n \"id\": 1,\n \"suggestion\": \"Confirm that the method 'importclass' is meant to change its behavior when 'class_name' is None. The new lines suggest 'class_name' will be derived from the 'module_name' in such cases, which can have unintended effects if not explicitly intended.\",\n \"filename\": \"test_file.py\",\n \"lineNumber\": 19,\n \"codeSnippet\": \"if not class_name:\n module_name, class_name = module_name.rsplit('.', 1)\"\n }\n ]\n```"
+ }
+ }
+ ]
+}