-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Testing #8
Open
DhruvK1184
wants to merge
1
commit into
main
Choose a base branch
from
Testing_branch
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Testing #8
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,16 +43,25 @@ def get_context(patch): | |
# print("prompt: ",prompt,"patch: ",patch) | ||
return prompt + patch | ||
|
||
def get_context_for_individual_line(patch): | ||
prompt = '' | ||
# Open the prompt file and read its contents into a variable | ||
with open('linePrompt.txt', 'r') as file: | ||
prompt = file.read() | ||
|
||
print("prompt: ",prompt,"patch: ",patch) | ||
return prompt + patch | ||
|
||
|
||
# Function to post a review comment on a pull request | ||
# def post_review_comment(body, pr_number, repo_name): | ||
# url = f'https://api.github.com/repos/{REPO_OWNER}/{repo_name}/pulls/{pr_number}/reviews' | ||
# data = { | ||
# "body": body, | ||
# "event": "COMMENT" | ||
# } | ||
# response = requests.post(url, headers=get_headers(), data=json.dumps(data)) | ||
# return response.json() | ||
def post_review_comment(body, pr_number, repo_name): | ||
url = f'https://api.github.com/repos/{REPO_OWNER}/{repo_name}/pulls/{pr_number}/reviews' | ||
data = { | ||
"body": body, | ||
"event": "COMMENT" | ||
} | ||
response = requests.post(url, headers=get_headers(), data=json.dumps(data)) | ||
return response.json() | ||
|
||
|
||
# Function to get the files changed in a specific pull request | ||
|
@@ -97,9 +106,9 @@ def authenticate_request(event, context): | |
|
||
def lambda_handler(event, context): | ||
|
||
authenticated, response = authenticate_request(event, context) | ||
if not authenticated: | ||
return response | ||
# authenticated, response = authenticate_request(event, context) | ||
# if not authenticated: | ||
# return response | ||
|
||
pr_number = '' | ||
repo_name = '' | ||
|
@@ -112,7 +121,6 @@ def lambda_handler(event, context): | |
'body': json.dumps('Invalid payload format') | ||
} | ||
#print(payload) | ||
|
||
if payload.get('action') == 'opened' or payload.get('action') == 'synchronize': | ||
# Extract the pull request number and repository name | ||
pr_number = payload['pull_request']['number'] | ||
|
@@ -130,13 +138,9 @@ def lambda_handler(event, context): | |
} | ||
|
||
files = get_pull_request_files(pr_number, repo_name) | ||
|
||
commit_id=payload['pull_request']['head']['sha'] | ||
openai_review_concatenated = openai_review_comments(files, pr_number, repo_name) | ||
post_line_level_comment(pr_number, repo_name, commit_id, openai_review_concatenated) | ||
|
||
# print(i,openai_review_concatenated[i].path) | ||
# print(i,openai_review_concatenated[i].position) | ||
# post_review_comment(body=openai_review_concatenated, pr_number=pr_number, repo_name=repo_name) | ||
print("openai comment",openai_review_concatenated) | ||
# print("individual comment") | ||
# review_comments_on_lines(files) | ||
# print(f'comment posted on #{pr_number} in repository {repo_name}') | ||
|
@@ -145,225 +149,134 @@ def lambda_handler(event, context): | |
'body': json.dumps(f'comment posted on #{pr_number} in repository {repo_name}') | ||
} | ||
|
||
def post_line_level_comment(pr_number, repo_name, commit_id, openai_review_concatenated): | ||
for i, review_comment in enumerate(openai_review_concatenated): | ||
body = review_comment.get('body') | ||
path = review_comment.get('path') | ||
start_line = review_comment.get('start_line') | ||
line = review_comment.get('line') | ||
start_side = review_comment.get('start_side') | ||
side = review_comment.get('side') | ||
diff_hunk = review_comment.get('diff_hunk') | ||
position = review_comment.get('position') | ||
|
||
# Validate that start_line precedes line | ||
# if start_line is not None and line is not None and start_line >= line: | ||
# print(f"Invalid comment data: start_line ({start_line}) must be less than line ({line}).") | ||
# continue | ||
|
||
if body and path and commit_id and start_line and line and start_side and side: | ||
# print("body: ", body) | ||
# print("path: ", path) | ||
# print("commit_id: ", commit_id) | ||
# # print("start_line: ", start_line) | ||
# # print("line: ", line) | ||
# # print("start_side: ", start_side) | ||
# print("side: ", side) | ||
# print("pr_number", pr_number) | ||
# print("repo_name", repo_name) | ||
# print("diff_hunk", diff_hunk) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uncomment the |
||
# print("position", position) | ||
# print("_______________") | ||
if side == "RIGHT": | ||
post_review_comment_on_line(pr_number, repo_name, path, body, commit_id,side, diff_hunk, position) | ||
|
||
|
||
def openai_review_comments(files, pr_number, repo_name): | ||
openai_review_concatenated = [] | ||
openai_review_concatenated = '' | ||
|
||
# Handle batch processing if files exceed 10 | ||
if len(files) >= 10: | ||
num_batches = len(files) // 10 | ||
batch_size = (len(files) + num_batches - 1) // num_batches | ||
batches = [files[i:i + batch_size] for i in range(0, len(files), batch_size)] | ||
for batch in batches: | ||
concatenated_patch = ''.join(file.get('patch', '') for file in batch) | ||
batch_review = generate_openai(get_context(concatenated_patch)) | ||
openai_review_concatenated.extend(batch_review) | ||
openai_review_concatenated += generate_openai( | ||
get_context(concatenated_patch), | ||
get_context_for_individual_line(concatenated_patch) | ||
) | ||
else: | ||
patch = get_patch_from_pr(pr_number, repo_name) | ||
context = get_context(patch) | ||
openai_review_concatenated = generate_openai(context) | ||
linePrompt = get_context_for_individual_line(patch) | ||
openai_review_concatenated = generate_openai(context, linePrompt) | ||
|
||
# Convert the list of review comments to a single object | ||
return openai_review_concatenated | ||
|
||
|
||
|
||
def generate_openai(context): | ||
openai_response = [] # Initialize an empty string to accumulate response content | ||
|
||
tools = [ | ||
def generate_openai(context,linePrompt): | ||
# with open('system.txt', 'r') as file: | ||
# system = file.read() | ||
# linePrompt = '' | ||
# with open('linePrompt.txt', 'r') as file: | ||
# linePrompt = file.read() | ||
openai_response = '' | ||
functions = [ | ||
{ | ||
"type": "function", | ||
"function": { | ||
"name": "post_review_comment_on_line", | ||
"description": "Post a review comment on a specific range of lines in a file within a commit.", | ||
"parameters": { | ||
"type": "object", | ||
"properties": { | ||
"body": { | ||
"type": "string", | ||
"description": "The body text of the review comment to be posted." | ||
}, | ||
"path": { | ||
"type": "string", | ||
"description": "The path to the file in which the review comment will be posted." | ||
}, | ||
"commit_id": { | ||
"type": "string", | ||
"description": "The ID of the commit that contains the modified file." | ||
}, | ||
"start_line": { | ||
"type": "integer", | ||
"description": "The starting line number of the range in the file where the comment should be applied." | ||
}, | ||
"line": { | ||
"type": "integer", | ||
"description": "The ending line number of the range in the file where the comment should be applied." | ||
}, | ||
"start_side": { | ||
"type": "string", | ||
"description": "The side of the diff where the comment starts. LEFT for deleted lines and RIGHT for added lines.", | ||
"enum": ["LEFT", "RIGHT"] | ||
}, | ||
"side": { | ||
"type": "string", | ||
"description": "The side of the diff where the comment ends. LEFT for deleted lines and RIGHT for added lines.", | ||
"enum": ["LEFT", "RIGHT"] | ||
}, | ||
"diff_hunk": { | ||
"type": "string", | ||
"description": "The diff hunk of the comment." | ||
}, | ||
"position": { | ||
"type": "integer", | ||
"description": "The line number in the file where the comment should be applied." | ||
}, | ||
"in_reply_to": { | ||
"type": "string", | ||
"description": "The ID of the review comment to which the new comment should be a reply." | ||
}, | ||
"subject_type": { | ||
"type": "string", | ||
"description": "The type of the subject of the review comment. Can be either 'REVIEW' or 'ISSUE'.", | ||
} | ||
"name": "post_review_comment_on_line", | ||
"description": "Post the comment on the specific line in the pull request", | ||
"parameters": { | ||
"type": "object", | ||
"properties": { | ||
"body": { | ||
"type": "string", | ||
"description": "The body of the review comment" | ||
}, | ||
"required": ["path", "body", "commit_id", "start_line", "line", "start_side", "side", "diff_hunk", "position"] | ||
} | ||
} | ||
} | ||
"position": { | ||
"type": "integer", | ||
"description": "The line number in the file" | ||
}, | ||
"path": { | ||
"type": "string", | ||
"description": "The path of the file" | ||
} | ||
}, | ||
"required": ["path","position","body"] | ||
} | ||
} | ||
] | ||
|
||
|
||
# Create a streaming completion request | ||
stream = openai_client.chat.completions.create( | ||
model="gpt-4o", | ||
# messages=[{"role": "system", "content": system},{"role": "user", "content": context}], | ||
messages=[ | ||
{"role": "user", "content": context} | ||
{"role": "user", "content": context}, | ||
{"role":"user","content":linePrompt} | ||
], | ||
tools=tools, | ||
# stream=True # Enable streaming | ||
tools=functions, | ||
stream=True, | ||
) | ||
# print("context",context) | ||
# Extract tool calls from the response | ||
choices = stream.choices | ||
# print(choices) | ||
for choice in choices: | ||
if hasattr(choice.message, 'tool_calls'): | ||
for tool_call in choice.message.tool_calls: | ||
if tool_call.function: | ||
function_arguments = tool_call.function.arguments | ||
if function_arguments: | ||
try: | ||
# Load the function arguments as JSON | ||
arguments_dict = json.loads(function_arguments) | ||
# Extract the 'body' field | ||
body = arguments_dict.get('body') | ||
path = arguments_dict.get('path') | ||
commit_id = arguments_dict.get('commit_id') | ||
start_line = arguments_dict.get('start_line') | ||
line = arguments_dict.get('line') | ||
start_side = arguments_dict.get('start_side') | ||
side = arguments_dict.get('side') | ||
diff_hunk = arguments_dict.get('diff_hunk') | ||
|
||
position = arguments_dict.get('position') | ||
in_reply_to = arguments_dict.get('in_reply_to') | ||
subject_type = arguments_dict.get('subject_type') | ||
# print("Extracted body:", body) | ||
# print('path,',path) | ||
# print('position',position) | ||
openai_response.append({ | ||
"body":body, | ||
"path":path, | ||
"commit_id":commit_id, | ||
"start_line":start_line, | ||
"line":line, | ||
"start_side":start_side, | ||
"side":side, | ||
"diff_hunk":diff_hunk, | ||
|
||
"position":position, | ||
"in_reply_to":in_reply_to, | ||
"subject_type":subject_type | ||
}) | ||
except json.JSONDecodeError as e: | ||
print("Error decoding JSON:", e) | ||
else: | ||
print("Function arguments are empty.") | ||
# print('openai_response',openai_response) | ||
print("stream",stream) | ||
for chunk in stream: | ||
if chunk.choices[0].delta.content is not None: | ||
openai_response = openai_response + chunk.choices[0].delta.content | ||
# print("openai_response",openai_response) | ||
#print(openai_response) | ||
return openai_response | ||
|
||
|
||
|
||
|
||
|
||
def post_review_comment_on_line(pr_number, repo_name, path, body, commit_id, side, diff_hunk, position): | ||
|
||
# Validate that required fields are not None | ||
if path is None or body is None or commit_id is None: | ||
raise ValueError("Missing required fields.") | ||
|
||
if side != "RIGHT": | ||
print(f"Skipping comment on side {side} for path {path}.") | ||
return None | ||
|
||
# def review_comments_on_lines(files): | ||
# # print("files",files) | ||
# for file in files: | ||
# file_name = file.get('filename') or file['filename'] | ||
# patch = file.get('patch') or file['patch'] | ||
|
||
# if not patch: | ||
# continue | ||
|
||
# # Split the patch into lines | ||
# patch_lines = patch.split('\n') | ||
# line_number_in_file = 0 | ||
# # print(patch) | ||
# for patch_line in patch_lines: | ||
# # Git diff format uses lines that start with '+' to indicate additions | ||
# if patch_line.startswith('+') and not patch_line.startswith('+++'): | ||
# line_number_in_file += 1 | ||
|
||
# # Generate a review comment using OpenAI | ||
# context = get_context(patch_line) | ||
# review_comment = generate_openai(context) | ||
|
||
# # Post the review comment on the specific line in the pull request | ||
# # print(file_name) | ||
# # print(review_comment) | ||
# # print(line_number_in_file) | ||
# # post_review_comment_on_line( | ||
# # body=review_comment, | ||
# # pr_number=pr_number, | ||
# # repo_name=repo_name, | ||
# # path=file_name, | ||
# # position=line_number_in_file | ||
# # ) | ||
|
||
|
||
def post_review_comment_on_line(body, pr_number, repo_name, path, position): | ||
url = f'https://api.github.com/repos/{REPO_OWNER}/{repo_name}/pulls/{pr_number}/comments' | ||
data = { | ||
"body": body, | ||
"path": path, | ||
"commit_id": commit_id, | ||
# "start_line": start_line, | ||
# "line": line, | ||
# "start_side": start_side, | ||
"side": side, | ||
"diff_hunk": diff_hunk, | ||
"position": position | ||
"position": position, | ||
} | ||
|
||
# Remove keys with None values to avoid sending unnecessary fields | ||
data = {k: v for k, v in data.items() if v is not None} | ||
|
||
response = requests.post(url, headers=get_headers(), data=json.dumps(data)) | ||
print("posting completed") | ||
print(response.json()) | ||
return response.json() | ||
|
||
|
||
# if __name__ == '__main__': | ||
# with open('sample_event.json', 'r') as fileVariable: | ||
# event_text = json.load(fileVariable) | ||
|
||
# # event = ast.literal_eval(event_text) | ||
# # event = json.loads(event_text) | ||
# context = '' | ||
# lambda_handler(event_text, context) | ||
|
||
|
||
|
||
if __name__ == '__main__': | ||
with open('sample.json', 'r') as fileVariable: | ||
event_text = json.load(fileVariable) | ||
|
||
# event = ast.literal_eval(event_text) | ||
# event = json.loads(event_text) | ||
context = '' | ||
lambda_handler(event_text, context) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented-out code should be removed to maintain code cleanliness and readability.