Skip to content

Commit

Permalink
Updated pullrequest validation service for it to directly gather file…
Browse files Browse the repository at this point in the history
…s that were changed from the PR instead of commits and also prompt template was rewritten. Updated dtos respectively to the new requirements and updated ai validation listener to pass github name as well. Also added max tokens option to spring ai properties.
  • Loading branch information
Bohdan committed Feb 10, 2024
1 parent ba861d0 commit 3624ce6
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommitFileDto {
public class PullrequestPatchDto {
private String filename;
private String code;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import lombok.Data;
import lombok.NoArgsConstructor;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHPullRequestCommitDetail;


@Data
Expand All @@ -15,8 +14,7 @@
@NoArgsConstructor
public class QueuedValidationProcessDto {
private String prompt;
private String committer;
private String traineeGitName;
private GHPullRequest pullRequest;
private GHPullRequestCommitDetail commitDetail;
private Map<String, Integer> fileCodeLines;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.community.tools.service.github;

import com.community.tools.dto.CommitFileDto;
import com.community.tools.dto.OpenAiValidationResponseDto;
import com.community.tools.dto.PullrequestPatchDto;
import com.community.tools.dto.QueuedValidationProcessDto;
import com.community.tools.model.TaskNameAndStatus;
import com.community.tools.service.NotificationService;
import com.community.tools.service.openai.OpenAiService;
import com.fasterxml.jackson.core.JsonProcessingException;
Expand All @@ -11,12 +12,9 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.stream.Collectors;
import org.kohsuke.github.GHCommit;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHPullRequestCommitDetail;
import org.kohsuke.github.GHPullRequestReviewBuilder;
import org.kohsuke.github.GHPullRequestReviewEvent;
import org.kohsuke.github.GHRepository;
Expand All @@ -31,27 +29,28 @@ public class PullRequestValidationService {
private final OpenAiService openAiService;
private final NotificationService notificationService;
private final Queue<QueuedValidationProcessDto> requests = new LinkedList<>();
private static final String PROMPT_TEMPLATE = "Provide me with the code review where you "
+ "point out lines of code that have some issues and make an comment "
+ "what are they and why. Then rate me the code on the scale from 1 to 10 "
+ "where 1 is the poorest. Rate code considering it's trainee developer."
+ "The code will be provided in JSON format as "
+ "[{filename: ${filename}, code: ${code}}]. Ignore git patch headers. "
+ "The code to rate is: %s"
+ ". Return me response in the JSON format of {"
+ " rating: ${rating_integer},"
+ " files: ["
+ " filename: ${filename},"
+ " comments: ["
+ " {"
+ " line: ${line_number_integer},"
+ " comment: ${comment}"
+ " }"
+ " ]"
private static final String PROMPT_TEMPLATE = "Rate the provided as git patch "
+ "code(line with - is deleted line and + is added) on a scale from 1 to 10, "
+ "considering its quality, readability and efficiency. "
+ "Additionally, provide constructive comments for improvement, "
+ "but avoid duplicating comments with the same issues and sense. "
+ "Please return the feedback in the following format:"
+ "{"
+ " \"rating\": ${rating_integer},"
+ " \"files\": ["
+ " {"
+ " \"filename\": \"${filename}\","
+ " \"comments\": ["
+ " {"
+ " \"line\": ${line_number},"
+ " \"comment\": \"${comment}\""
+ " }"
+ " ]"
+ " }"
+ " ]"
+ "} return only strictly json response.";
private static final String NOTIFICATION_MESSAGE_TEMPLATE
= "The commit %s was reviewed. Please check it out.";
+ "}"
+ "The code is provided in json format [{filename: ${filename}, code: ${code}}]. "
+ "The code is: %s";

/**
* Constructor for the service.
Expand All @@ -72,52 +71,37 @@ public PullRequestValidationService(GitHubConnectService gitService,

/**
* Main method of the service that retrieves Feedback PR by its id(1),
* iterates through its commits(except those by bot created)
* and gathers all commit files into one prompt to put it in the queue of validation.
* and gathers all PR files into one prompt to put it in the queue of validation.
*
* @param repositoryName name of the repository that needs its PR to be validated.
* @throws RuntimeException If github api doesn't find requested objects
*/
public void validatePullRequest(String repositoryName) {
public void validatePullRequest(String repositoryName, String traineeGitName) {
GHRepository repository = gitService.getGitHubRepositoryByName(repositoryName);
try {
GHPullRequest pullRequest = repository.getPullRequest(1);

List<GHPullRequestCommitDetail> userCommits = pullRequest
.listCommits().toList()
.stream()
.filter(commit ->
!commit.getCommit().getAuthor().getName().equals("github-classroom[bot]")
)
.collect(Collectors.toList());

for (GHPullRequestCommitDetail commitDetail : userCommits) {
List<CommitFileDto> fileList = new ArrayList<>();
List<GHCommit.File> commitFiles = repository
.getCommit(commitDetail.getSha()).getFiles()
.stream().filter(Objects::nonNull).collect(Collectors.toList());

for (GHCommit.File file : commitFiles) {
fileList.add(new CommitFileDto(file.getFileName(), file.getPatch()));
}
String prompt = String.format(PROMPT_TEMPLATE, objectMapper.writeValueAsString(fileList));

requests.add(QueuedValidationProcessDto.builder()
.prompt(prompt)
.committer(repository.getCommit(commitDetail.getSha()).getAuthor().getLogin())
.pullRequest(pullRequest)
.commitDetail(commitDetail)
.fileCodeLines(fileList.stream()
.collect(
Collectors.toMap(
CommitFileDto::getFilename,
commitFileDto -> commitFileDto.getCode().split("\n").length
)
List<PullrequestPatchDto> fileList = new ArrayList<>();
pullRequest.listFiles().forEach(
file -> fileList.add(
new PullrequestPatchDto(file.getFilename(), file.getPatch()))
);

)
)
.build());
}
String prompt = String.format(PROMPT_TEMPLATE, objectMapper.writeValueAsString(fileList));
requests.add(QueuedValidationProcessDto.builder()
.prompt(prompt)
.traineeGitName(traineeGitName)
.pullRequest(pullRequest)
.fileCodeLines(fileList.stream()
.collect(
Collectors.toMap(
PullrequestPatchDto::getFilename,
pullrequestPatchDto ->
pullrequestPatchDto.getCode().split("\n").length
)
)
)
.build());
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand All @@ -140,7 +124,6 @@ private void processValidation() {
QueuedValidationProcessDto process = requests.poll();
String prompt = process.getPrompt();
GHPullRequest pullRequest = process.getPullRequest();
GHPullRequestCommitDetail commitDetail = process.getCommitDetail();
GHPullRequestReviewBuilder review = pullRequest.createReview();
try {
String response = openAiService.processPrompt(prompt);
Expand All @@ -151,25 +134,26 @@ private void processValidation() {
int codeLines = process.getFileCodeLines().get(file.getFilename());
file.getComments().forEach(comment -> {
if (codeLines > comment.getLine()) {
review.commitId(commitDetail.getSha());
review.comment(comment.getComment(), file.getFilename(), comment.getLine());
}
});
});
if (openAiResponse.getRating() >= 7) {
review.event(GHPullRequestReviewEvent.COMMENT);
} else {
review.event(GHPullRequestReviewEvent.REQUEST_CHANGES);
}
review.body("OpenAI previous review of commit "
+ commitDetail.getSha() + ". The rating is "
+ openAiResponse.getRating() + "/10.");
GHPullRequestReviewEvent taskStatus = openAiResponse.getRating() >= 7
? GHPullRequestReviewEvent.COMMENT : GHPullRequestReviewEvent.REQUEST_CHANGES;

review.event(taskStatus);
review.body("OpenAI previous review of the pullrequest. "
+ "The rating is "
+ openAiResponse.getRating() + "/10.");
review.create();
notificationService.sendNotificationMessage(
process.getCommitter(),
String.format(NOTIFICATION_MESSAGE_TEMPLATE, commitDetail.getSha())
);

notificationService.sendPullRequestUpdateNotification(
process.getTraineeGitName(),
List.of(new TaskNameAndStatus(
pullRequest.getBase().getRepository().getName(),
pullRequest.getUrl().toString(),
taskStatus.toString())
));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void handleEvent(TaskStatusChangeEventDto event) {
if (event.getTaskStatus().equals(TaskStatus.READY_FOR_REVIEW)
&& !event.isWithNewChanges()) {
pullRequestValidationService.validatePullRequest(githubOrgName + "/"
+ event.getTaskName() + "-" + event.getTraineeGitName());
+ event.getTaskName() + "-" + event.getTraineeGitName(), event.getTraineeGitName());
}
}
}
1 change: 1 addition & 0 deletions bot/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ spring.ai.openai.api-key=${OPEN_AI_TOKEN}
spring.ai.openai.chat.options.temperature=0.1
spring.ai.openai.chat.options.model=gpt-3.5-turbo
spring.ai.openai.chat.options.response-format=text
spring.ai.openai.chat.options.max-tokens=1000


#notification
Expand Down

0 comments on commit 3624ce6

Please sign in to comment.