Refactor: dynamic loading for ChatGptClient
The ChatGptClient class has been moved to
`mode.stateless...ChatGptClientStateless` and is now loaded
dynamically based on the `gptMode` setting, paving the way for the
upcoming ChatGptClientStateful class.
Change-Id: I19c2a1a62238208e2ba0cc5a759f35eb65c2e011
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 952011f..01e3b69 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
@@ -4,7 +4,7 @@
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
import com.googlesource.gerrit.plugins.chatgpt.data.ChangeSetDataHandler;
-import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptClient;
+import com.googlesource.gerrit.plugins.chatgpt.mode.ModeClassLoader;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritClient;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritClientReview;
@@ -16,10 +16,15 @@
import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.api.gerrit.GerritComment;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.data.ChangeSetData;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.review.ReviewBatch;
+import com.googlesource.gerrit.plugins.chatgpt.mode.stateless.client.api.chatgpt.ChatGptClientStateless;
+import com.googlesource.gerrit.plugins.chatgpt.mode.interfaces.client.api.chatgpt.IChatGptClient;
+import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
+import static com.googlesource.gerrit.plugins.chatgpt.utils.ClassUtils.registerDynamicClasses;
+
@Slf4j
public class PatchSetReviewer {
private static final String SPLIT_REVIEW_MSG = "Too many changes. Please consider splitting into patches smaller " +
@@ -27,18 +32,18 @@
private final Gson gson = new Gson();
private final GerritClient gerritClient;
- private final ChatGptClient chatGptClient;
private Configuration config;
+ @Getter
+ private IChatGptClient chatGptClient;
private GerritCommentRange gerritCommentRange;
private List<ReviewBatch> reviewBatches;
private List<GerritComment> commentProperties;
private List<Integer> reviewScores;
@Inject
- PatchSetReviewer(GerritClient gerritClient, ChatGptClient chatGptClient) {
+ PatchSetReviewer(GerritClient gerritClient) {
this.gerritClient = gerritClient;
- this.chatGptClient = chatGptClient;
}
public void review(Configuration config, GerritChange change) throws Exception {
@@ -126,6 +131,10 @@
log.warn("Patch set too large. Skipping review. changeId: {}", change.getFullChangeId());
return String.format(SPLIT_REVIEW_MSG, config.getMaxReviewLines());
}
+ chatGptClient = (IChatGptClient) ModeClassLoader.getInstance(
+ "client.api.chatgpt.ChatGptClient", config);
+ registerDynamicClasses(ChatGptClientStateless.class);
+
return chatGptClient.ask(config, change, patchSet);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptTools.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptTools.java
index cb86332..30fff94 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptTools.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptTools.java
@@ -7,7 +7,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
-class ChatGptTools {
+public class ChatGptTools {
private final static Gson gson = new Gson();
public static ChatGptRequest retrieveTools() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/interfaces/client/api/chatgpt/IChatGptClient.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/interfaces/client/api/chatgpt/IChatGptClient.java
new file mode 100644
index 0000000..4c307ed
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/interfaces/client/api/chatgpt/IChatGptClient.java
@@ -0,0 +1,10 @@
+package com.googlesource.gerrit.plugins.chatgpt.mode.interfaces.client.api.chatgpt;
+
+import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
+import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange;
+
+public interface IChatGptClient {
+ String ask(Configuration config, String changeId, String patchSet) throws Exception;
+ String ask(Configuration config, GerritChange change, String patchSet) throws Exception;
+ String getRequestBody();
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptClient.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateless/client/api/chatgpt/ChatGptClientStateless.java
similarity index 94%
rename from src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptClient.java
rename to src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateless/client/api/chatgpt/ChatGptClientStateless.java
index 88188d0..51d3967 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateless/client/api/chatgpt/ChatGptClientStateless.java
@@ -1,4 +1,4 @@
-package com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt;
+package com.googlesource.gerrit.plugins.chatgpt.mode.stateless.client.api.chatgpt;
import com.google.common.net.HttpHeaders;
import com.google.gson.Gson;
@@ -7,9 +7,11 @@
import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.HttpClientWithRetry;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.UriResourceLocator;
+import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptTools;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.prompt.ChatGptPrompt;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.api.chatgpt.*;
+import com.googlesource.gerrit.plugins.chatgpt.mode.interfaces.client.api.chatgpt.IChatGptClient;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
@@ -25,7 +27,7 @@
@Slf4j
@Singleton
-public class ChatGptClient {
+public class ChatGptClientStateless implements IChatGptClient {
private static final int REVIEW_ATTEMPT_LIMIT = 3;
@Getter
private String requestBody;
@@ -35,6 +37,7 @@
private final HttpClientWithRetry httpClientWithRetry = new HttpClientWithRetry();
private boolean isCommentEvent = false;
+ @Override
public String ask(Configuration config, String changeId, String patchSet) throws Exception {
for (int attemptInd = 0; attemptInd < REVIEW_ATTEMPT_LIMIT; attemptInd++) {
HttpRequest request = createRequest(config, changeId, patchSet);
@@ -56,6 +59,7 @@
throw new RuntimeException("Failed to receive valid ChatGPT response");
}
+ @Override
public String ask(Configuration config, GerritChange change, String patchSet) throws Exception {
isCommentEvent = change.getIsCommentEvent();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptParameters.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateless/client/api/chatgpt/ChatGptParameters.java
similarity index 93%
rename from src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptParameters.java
rename to src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateless/client/api/chatgpt/ChatGptParameters.java
index 4670a67..a4bc242 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/common/client/api/chatgpt/ChatGptParameters.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateless/client/api/chatgpt/ChatGptParameters.java
@@ -1,4 +1,4 @@
-package com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt;
+package com.googlesource.gerrit.plugins.chatgpt.mode.stateless.client.api.chatgpt;
import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.ClientBase;
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 a588594..9565234 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
@@ -25,7 +25,6 @@
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.UriResourceLocator;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritClient;
-import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptClient;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.prompt.ChatGptPrompt;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
@@ -259,8 +258,7 @@
@Test
public void patchSetCreatedOrUpdatedStreamed() throws InterruptedException, NoSuchProjectException, ExecutionException {
GerritClient gerritClient = new GerritClient();
- ChatGptClient chatGptClient = new ChatGptClient();
- PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient, chatGptClient);
+ PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient);
ConfigCreator mockConfigCreator = mock(ConfigCreator.class);
when(mockConfigCreator.createConfig(ArgumentMatchers.any())).thenReturn(config);
String reviewUserPrompt = joinWithNewLine(Arrays.asList(
@@ -291,7 +289,7 @@
WireMock.urlEqualTo(gerritSetReviewUri(getGerritChange().getFullChangeId())));
List<LoggedRequest> loggedRequests = WireMock.findAll(requestPatternBuilder);
Assert.assertEquals(1, loggedRequests.size());
- JsonObject gptRequestBody = gson.fromJson(chatGptClient.getRequestBody(), JsonObject.class);
+ JsonObject gptRequestBody = gson.fromJson(patchSetReviewer.getChatGptClient().getRequestBody(), JsonObject.class);
JsonArray prompts = gptRequestBody.get("messages").getAsJsonArray();
String systemPrompt = prompts.get(0).getAsJsonObject().get("content").getAsString();
Assert.assertEquals(expectedSystemPromptReview, systemPrompt);
@@ -309,8 +307,7 @@
when(globalConfig.getBoolean(Mockito.eq("enabledVoting"), Mockito.anyBoolean()))
.thenReturn(true);
GerritClient gerritClient = new GerritClient();
- ChatGptClient chatGptClient = new ChatGptClient();
- PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient, chatGptClient);
+ PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient);
ConfigCreator mockConfigCreator = mock(ConfigCreator.class);
when(mockConfigCreator.createConfig(ArgumentMatchers.any())).thenReturn(config);
String reviewVoteUserPrompt = joinWithNewLine(Arrays.asList(
@@ -348,7 +345,7 @@
WireMock.urlEqualTo(gerritSetReviewUri(getGerritChange().getFullChangeId())));
List<LoggedRequest> loggedRequests = WireMock.findAll(requestPatternBuilder);
Assert.assertEquals(1, loggedRequests.size());
- JsonObject gptRequestBody = gson.fromJson(chatGptClient.getRequestBody(), JsonObject.class);
+ JsonObject gptRequestBody = gson.fromJson(patchSetReviewer.getChatGptClient().getRequestBody(), JsonObject.class);
JsonArray prompts = gptRequestBody.get("messages").getAsJsonArray();
String userPrompt = prompts.get(1).getAsJsonObject().get("content").getAsString();
Assert.assertEquals(reviewVoteUserPrompt, userPrompt);
@@ -362,8 +359,7 @@
when(globalConfig.getString(Mockito.eq("disabledGroups"), Mockito.anyString()))
.thenReturn(GERRIT_USER_GROUP);
GerritClient gerritClient = new GerritClient();
- ChatGptClient chatGptClient = new ChatGptClient();
- PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient, chatGptClient);
+ PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient);
ConfigCreator mockConfigCreator = mock(ConfigCreator.class);
when(mockConfigCreator.createConfig(ArgumentMatchers.any())).thenReturn(config);
@@ -386,8 +382,7 @@
public void gptMentionedInComment() throws InterruptedException, NoSuchProjectException, ExecutionException {
GerritChange gerritChange = getGerritChange();
GerritClient gerritClient = new GerritClient();
- ChatGptClient chatGptClient = new ChatGptClient();
- PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient, chatGptClient);
+ PatchSetReviewer patchSetReviewer = new PatchSetReviewer(gerritClient);
ConfigCreator mockConfigCreator = mock(ConfigCreator.class);
when(config.getGerritUserName()).thenReturn(GERRIT_GPT_USERNAME);
when(mockConfigCreator.createConfig(ArgumentMatchers.any())).thenReturn(config);
@@ -426,7 +421,7 @@
WireMock.urlEqualTo(gerritSetReviewUri(gerritChange.getFullChangeId())));
List<LoggedRequest> loggedRequests = WireMock.findAll(requestPatternBuilder);
Assert.assertEquals(1, loggedRequests.size());
- JsonObject gptRequestBody = gson.fromJson(chatGptClient.getRequestBody(), JsonObject.class);
+ JsonObject gptRequestBody = gson.fromJson(patchSetReviewer.getChatGptClient().getRequestBody(), JsonObject.class);
JsonArray prompts = gptRequestBody.get("messages").getAsJsonArray();
String userPrompt = prompts.get(1).getAsJsonObject().get("content").getAsString();
Assert.assertEquals(commentUserPrompt, userPrompt);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java
index c6bfcf9..f44da74 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java
@@ -1,11 +1,11 @@
package com.googlesource.gerrit.plugins.chatgpt.integration;
import com.googlesource.gerrit.plugins.chatgpt.config.Configuration;
-import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptClient;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritClient;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritClientReview;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.prompt.ChatGptPrompt;
import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.review.ReviewBatch;
+import com.googlesource.gerrit.plugins.chatgpt.mode.interfaces.client.api.chatgpt.IChatGptClient;
import lombok.extern.slf4j.Slf4j;
import org.junit.Ignore;
import org.junit.Test;
@@ -32,7 +32,7 @@
private GerritClient gerritClient;
@InjectMocks
- private ChatGptClient chatGptClient;
+ private IChatGptClient chatGptClient;
@Test
public void sayHelloToGPT() throws Exception {