[bitbucket-chatgpt-codereview ]Feature Improvement Request
Asked by ???:

1. Request for additional logic to split into multiple batches to call and combine the results when GPT token is exceeded

2. Added EXCLUX_FILES

i'm using it very well. thank you

**example (from gpt)**

schema = {

'OPENAI_API_KEY': {'type': 'string', 'required': True},

'BITBUCKET_ACCESS_TOKEN': {'type': 'string', 'required': True},

'MODEL': {'type': 'string', 'required': True, 'allowed': \['gpt-4-turbo-preview', 'gpt-3.5-turbo-0125'\]},

'ORGANIZATION': {'type': 'string', 'required': False},

'MESSAGE': {'type': 'string', 'required': False},

'FILES_TO_REVIEW': {'type': 'string', 'required': False},

'EXCLUDE_FILES': {'type': 'string', 'required': False}, # ??? ?? ??? ??

'CHATGPT_COMPLETION_FILEPATH': {'type': 'string', 'required': False},

'CHATGPT_CLIENT_FILEPATH': {'type': 'string', 'required': False},

'CHATGPT_PROMPT_MAX_TOKENS': {'type': 'integer', 'required': False, 'default': 0},

'DEBUG': {'type': 'boolean', 'required': False, 'default': False},

}

class ChatGPTCodereviewPipe(Pipe):

MAX_TOKENS = 4096 # ??? ?? ?? ?? ? ??

def __init__(self, \*args, \*\*kwargs):

super().__init__(\*args, \*\*kwargs)

self.auth_method_bitbucket = self.resolve_auth()

# Bitbucket

self.workspace = os.getenv('BITBUCKET_WORKSPACE')

self.repo_slug = os.getenv('BITBUCKET_REPO_SLUG')

self.bitbucket_client = BitbucketApiService(

self.auth_method_bitbucket, self.workspace, self.repo_slug)

# ChatGPT

self.open_api_key = self.get_variable('OPENAI_API_KEY')

self.organization = self.get_variable('ORGANIZATION')

self.model = self.get_variable('MODEL')

self.user_message_content = self.get_variable('MESSAGE')

self.files_to_review = self.get_variable("FILES_TO_REVIEW")

self.exclude_files = self.get_variable("EXCLUDE_FILES") # ??? ?? ??

self.completion_parameters_payload_file = self.get_variable('CHATGPT_COMPLETION_FILEPATH')

self.chatgpt_parameters_payload_file = self.get_variable('CHATGPT_CLIENT_FILEPATH')

self.chat_gpt_client = None

def get_diffs_to_review(self, pull_request_id):

diffs_text = self.bitbucket_client.get_pull_request_diffs(pull_request_id)

files_to_review = \[\]

if self.files_to_review and self.files_to_review.split(','):

files_to_review = self.files_to_review.split(',')

exclude_files = \[\]

if self.exclude_files and self.exclude_files.split(','):

exclude_files = self.exclude_files.split(',')

diffs = self.bitbucket_client.fetch_diffs(diffs_text, files_to_review, self.bitbucket_client.DIFF_DELIMITER)

# ??? ?? ???

if exclude_files:

diffs = \[diff for diff in diffs if not any(exclude_file in diff for exclude_file in exclude_files)\]

return diffs

def split_messages_into_batches(self, messages, model, max_tokens):

"""???? ?? ?? ?? ?? ?? ??? ??"""

batches = \[\]

current_batch = \[\]

current_tokens = 0

for message in messages:

message_tokens = self.chat_gpt_client.num_tokens_from_messages(\[message\], model)

if current_tokens + message_tokens \> max_tokens:

batches.append(current_batch)

current_batch = \[\]

current_tokens = 0

current_batch.append(message)

current_tokens += message_tokens

if current_batch:

batches.append(current_batch)

return batches

def get_suggestions(self, diffs_to_review):

messages = \[\]

default_messages_system = {

"role": "system",

"content": DEFAULT_SYSTEM_PROMPT_FOR_CODE_REVIEW

}

messages.append(default_messages_system)

if self.user_message_content:

messages.append({"role": "system", "content": self.user_message_content})

default_messages_diffs = {

"role": "user",

"content": str(diffs_to_review)

}

messages.append(default_messages_diffs)

# ???? ?? ??? ??

message_batches = self.split_messages_into_batches(messages, self.model, self.MAX_TOKENS)

all_suggestions = {}

for batch in message_batches:

self.log_info(f"Processing ChatGPT batch with {len(batch)} messages...")

completion_params = {

'model': self.model,

'messages': batch,

}

# get payload with params for completion

if self.completion_parameters_payload_file:

users_completion_params = self.load_yaml(self.completion_parameters_payload_file)

self.log_info(f"ChatGPT configuration: completion parameters: {users_completion_params}")

completion_params.update(users_completion_params)

self.log_info(f"ChatGPT configuration: messages: {batch}")

self.log_info("Processing ChatGPT...")

start_time = time.time()

completion = None

try:

completion = self.chat_gpt_client.create_completion(\*\*completion_params)

except BadRequestError as error:

self.fail(f"{str(error)}")

end_time = time.time()

self.log_debug(completion)

self.log_info(f"Processing ChatGPT takes: {round(end_time - start_time)} seconds")

self.log_info(f'ChatGPT completion tokens: {completion.usage}')

raw_suggestions = completion.choices\[0\].message.content

self.log_debug(raw_suggestions)

try:

suggestions = self.chat_gpt_client.fetch_json(raw_suggestions)

all_suggestions.update(suggestions)

except json.JSONDecodeError as error:

self.fail(str(error))

self.log_debug(all_suggestions)

return all_suggestions

[@Oleksandr Kyrdan](https://community.atlassian.com/t5/user/viewprofilepage/user-id/2885705)


Answers:
author: Oleksandr Kyrdan
body: Hi [@???](/t5/user/viewprofilepage/user-id/5440227)

Thanks for your contribution to the community and feedback!

We'll discuss this ideas with the team and notify you.

Also, pipe are open source and your are always welcome to make PR directly to the [bitbucket-chatgpt-codereview pipe's repository](https://bitbucket.org/atlassian/bitbucket-chatgpt-codereview).

Best regards,  
Oleksandr Kyrdan


Tags: ai

bitbucket-cloud

bitbucket-pipelines

chatgpt

cloud

code-quality

pipes