refactor: Split review task into chunks to avoid token limit

To accommodate the token limits for various GPT models:

gpt-35-turbo: 4096 tokens
gpt-4: 8192 tokens
gpt-4-32k: 32768 tokens

These limits include tokens from both the message array and model response. The combined token count of the messages array and max_tokens parameter must stay within these limits to avoid errors.
To address this, we:

Split the diff into separate review requests
Combine the individual requests into a single review

Automatic review for commit 2c4b0a55e8265901200bc1602b8934a4ada8eed0:
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code changes and provide feedback:\n' +
'  - Check for bugs and highlight them.\n' +
'  - Verify alignment with commit messages.\n' +
'  - Sort issues from major to minor.\n' +
'  - Ensure adherence to best practices and project guidelines:\n' +
'  - Code readability, maintainability, and documentation.\n' +
'  - Consistent naming conventions and coding style.\n' +
'  - Modular and organized functions and classes.\n' +
'  - Analyze performance and optimization:\n' +
'  - Identify potential performance bottlenecks.\n' +
'  - Suggest optimizations or efficient algorithms.\n' +
'  - Assess test coverage and quality:\n' +
'  - Confirm appropriate unit tests are added or updated.\n' +
'  - Check for untested edge cases.\n' +
'  - Determine if integration tests are needed.\n' +
'  - Evaluate code reusability:\n' +
'  - Encourage use of existing libraries, frameworks, or code snippets.\n' +
'  - Identify opportunities for reusable components or patterns.\n' +
'  - Confirm cross-browser and cross-platform compatibility:\n' +
'  - Provide security recommendations, if applicable.\n' +
'  - Check the commit message for clear descriptions of changes.\n' +
'  - Provide feedback as the numbered list.\n' +
'  - focus only on negative parts.\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
}
A description was given to help you assist in understand why these changes were made:
To accommodate the token limits for various GPT models:

gpt-35-turbo: 4096 tokens
gpt-4: 8192 tokens
gpt-4-32k: 32768 tokens

These limits include tokens from both the message array and model
response. The combined token count of the messages array and max_tokens
parameter must stay within these limits to avoid errors.
To address this, we:

Split the diff into separate review requests
Combine the individual requests into a single review

Do not provide feedback yet. I will follow-up with a diff of the change in a new message.

diff --git a/src/review.ts b/src/review.ts
index 7f7d295..763a778 100644
--- a/src/review.ts
+++ b/src/review.ts
@@ -25,13 +25,13 @@ const configuration = new Configuration({
const openai = new OpenAIApi(configuration);
-const systemMessage: ChatCompletionRequestMessage = {
+const reviewSystemMessage: ChatCompletionRequestMessage = {
role: 'system',
content:
'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',
};
-function createTaskMessage(title: string): ChatCompletionRequestMessage {
+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {
const content = `The change has the following title: ${title}.
Your task is:
@@ -115,32 +115,43 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {
};
}
+const summarySystemMessage: ChatCompletionRequestMessage = {

role: 'system',
content:
'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',
+};

+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {

const content = `
Your task is:

To make a summary of the reviews that are provided to the same code change.

Those reviews are on the different git diffs of the same git patch or pull request.

${reviewChunk.slice(0, MAX_CONTENT_SIZE)}

Make a summary of the reviews as the bullet points.
`;

return {
role: 'user',
content,
};
+}

export function logContext(gitDetails: GitDetails) {

console.info(systemMessage.content);
console.info(createTaskMessage(gitDetails.title));

console.info(reviewSystemMessage.content);
console.info(createReviewTaskMessage(gitDetails.title));
console.info(createDescriptionMessage(gitDetails.description).content);
console.info(createDiffMessage(gitDetails.diff).content);
}

-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {

if (verbose) logContext(gitDetails);

+async function completionRequest(

messages: ChatCompletionRequestMessage[],
verbose: boolean,
+): Promise<string | undefined> {
try {

const messages = [

 systemMessage,

 createTaskMessage(gitDetails.title),

 createDescriptionMessage(gitDetails.description),

 // The token limit for gpt-35-turbo is 4096 tokens, whereas the token

 // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These

 // limits include the token count from both the message array sent and the

 // model response. The number of tokens in the messages array combined

 // with the value of the max_tokens parameter must stay under these limits

 // or you'll receive an error.

 // TODO: combine into several requests if diff is too big

 ...splitDiff(gitDetails.diff).slice(0, 1),

 commandToExecuteTheTask(),

];
if (verbose) console.info('Messages:', messages);
if (verbose) console.info('Sending request to OpenAI API...');

@@ -157,3 +168,49 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri
return undefined;
}
}
+
+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {

if (verbose) logContext(gitDetails);

const diffs = splitDiff(gitDetails.diff);
const baseMessage = [
reviewSystemMessage,
createReviewTaskMessage(gitDetails.title),
createDescriptionMessage(gitDetails.description),
];

const messages: ChatCompletionRequestMessage[][] = [];
for (const d of diffs) {
messages.push([...baseMessage, d, commandToExecuteTheTask()]);
}

const reviews: string[] = [];
for await (const m of messages) {
const reviewChunk = await completionRequest(m, verbose);
if (reviewChunk) {

 reviews.push(reviewChunk);

}
}
if (reviews.length === 0) {
console.error('No reviews were generated.');
return undefined;
}

if (verbose) console.info('reviews:', reviews.join('\n'));
return reviews;
+}

+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {

// The token limit for gpt-35-turbo is 4096 tokens, whereas the token
// limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These
// limits include the token count from both the message array sent and the
// model response. The number of tokens in the messages array combined
// with the value of the max_tokens parameter must stay under these limits
// or you'll receive an error. Therefore, we need to split the diff into
// a separet review requests and then combine them into a single review.
const reviews = await requestReviews(gitDetails, verbose);
if (!reviews) return undefined;

const summaryTask = createSummaryTask(reviews.join('---\n'));
return await completionRequest([summarySystemMessage, summaryTask], verbose);
+}

Do not provide feedback yet. I will follow-up additional diff in a new message.
Messages: [
{
role: 'system',
content: 'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.'
},
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code changes and provide feedback:\n' +
'  - Check for bugs and highlight them.\n' +
'  - Verify alignment with commit messages.\n' +
'  - Sort issues from major to minor.\n' +
'  - Ensure adherence to best practices and project guidelines:\n' +
'  - Code readability, maintainability, and documentation.\n' +
'  - Consistent naming conventions and coding style.\n' +
'  - Modular and organized functions and classes.\n' +
'  - Analyze performance and optimization:\n' +
'  - Identify potential performance bottlenecks.\n' +
'  - Suggest optimizations or efficient algorithms.\n' +
'  - Assess test coverage and quality:\n' +
'  - Confirm appropriate unit tests are added or updated.\n' +
'  - Check for untested edge cases.\n' +
'  - Determine if integration tests are needed.\n' +
'  - Evaluate code reusability:\n' +
'  - Encourage use of existing libraries, frameworks, or code snippets.\n' +
'  - Identify opportunities for reusable components or patterns.\n' +
'  - Confirm cross-browser and cross-platform compatibility:\n' +
'  - Provide security recommendations, if applicable.\n' +
'  - Check the commit message for clear descriptions of changes.\n' +
'  - Provide feedback as the numbered list.\n' +
'  - focus only on negative parts.\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
},
{
role: 'user',
content: 'A description was given to help you assist in understand why these changes were made:\n' +
'-----\n' +
'To accommodate the token limits for various GPT models:\n' +
'- gpt-35-turbo: 4096 tokens\n' +
'- gpt-4: 8192 tokens\n' +
'- gpt-4-32k: 32768 tokens\n' +
'\n' +
'These limits include tokens from both the message array and model\n' +
'response. The combined token count of the messages array and max_tokens\n' +
'parameter must stay within these limits to avoid errors.\n' +
'\n' +
'To address this, we:\n' +
'- Split the diff into separate review requests\n' +
'- Combine the individual requests into a single review\n' +
'\n' +
'\n' +
'-----\n' +
'Do not provide feedback yet. I will follow-up with a diff of the change in a new message.\n'
},
{
role: 'user',
content: '\n' +
'-----\n' +
'diff --git a/src/review.ts b/src/review.ts\n' +
'index 7f7d295..763a778 100644\n' +
'--- a/src/review.ts\n' +
'+++ b/src/review.ts\n' +
'@@ -25,13 +25,13 @@ const configuration = new Configuration({\n' +
' \n' +
' const openai = new OpenAIApi(configuration);\n' +
' \n' +
'-const systemMessage: ChatCompletionRequestMessage = {\n' +
'+const reviewSystemMessage: ChatCompletionRequestMessage = {\n' +
"   role: 'system',\n" +
'   content:\n' +
"     'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',\n" +
' };\n' +
' \n' +
'-function createTaskMessage(title: string): ChatCompletionRequestMessage {\n' +
'+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {\n' +
'   const content = The change has the following title: ${title}.\n' +       ' \n' +       '   Your task is:\n' +       '@@ -115,32 +115,43 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {\n' +       '   };\n' +       ' }\n' +       ' \n' +       '+const summarySystemMessage: ChatCompletionRequestMessage = {\n' +       "+  role: 'system',\n" +       '+  content:\n' +       "+    'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',\n" +       '+};\n' +       '+\n' +       '+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {\n' +       '+  const content = \n' +
'+  Your task is:\n' +
'+  - To make a summary of the reviews that are provided to the same code change.\n' +
'+  - Those reviews are on the different git diffs of the same git patch or pull request.\n' +
'+\n' +
'+  -----\n' +
'+  ${reviewChunk.slice(0, MAX_CONTENT_SIZE)}\n' +
'+  -----\n' +
'+\n' +
'+  Make a summary of the reviews as the bullet points.\n' +
'+  ;\n' +       '+\n' +       '+  return {\n' +       "+    role: 'user',\n" +       '+    content,\n' +       '+  };\n' +       '+}\n' +       '+\n' +       ' export function logContext(gitDetails: GitDetails) {\n' +       '-  console.info(systemMessage.content);\n' +       '-  console.info(createTaskMessage(gitDetails.title));\n' +       '+  console.info(reviewSystemMessage.content);\n' +       '+  console.info(createReviewTaskMessage(gitDetails.title));\n' +       '   console.info(createDescriptionMessage(gitDetails.description).content);\n' +       '   console.info(createDiffMessage(gitDetails.diff).content);\n' +       ' }\n' +       ' \n' +       '-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {\n' +       '-  if (verbose) logContext(gitDetails);\n' +       '-\n' +       '+async function completionRequest(\n' +       '+  messages: ChatCompletionRequestMessage[],\n' +       '+  verbose: boolean,\n' +       '+): Promise<string | undefined> {\n' +       '   try {\n' +       '-    const messages = [\n' +       '-      systemMessage,\n' +       '-      createTaskMessage(gitDetails.title),\n' +       '-      createDescriptionMessage(gitDetails.description),\n' +       '-      // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n' +       '-      // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n' +       '-      // limits include the token count from both the message array sent and the\n' +       '-      // model response. The number of tokens in the messages array combined\n' +       '-      // with the value of the max_tokens parameter must stay under these limits\n' +       "-      // or you'll receive an error.\n" +       '-      // TODO: combine into several requests if diff is too big\n' +       '-      ...splitDiff(gitDetails.diff).slice(0, 1),\n' +       '-      commandToExecuteTheTask(),\n' +       '-    ];\n' +       '-\n' +       "     if (verbose) console.info('Messages:', messages);\n" +       "     if (verbose) console.info('Sending request to OpenAI API...');\n" +       ' \n' +       '@@ -157,3 +168,49 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri\n' +       '     return undefined;\n' +       '   }\n' +       ' }\n' +       '+\n' +       '+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {\n' +       '+  if (verbose) logContext(gitDetails);\n' +       '+\n' +       '+  const diffs = splitDiff(gitDetails.diff);\n' +       '+  const baseMessage = [\n' +       '+    reviewSystemMessage,\n' +       '+    createReviewTaskMessage(gitDetails.title),\n' +       '+    createDescriptionMessage(gitDetails.description),\n' +       '+  ];\n' +       '+\n' +       '+  const messages: ChatCompletionRequestMessage[][] = [];\n' +       '+  for (const d of diffs) {\n' +       '+    messages.push([...baseMessage, d, commandToExecuteTheTask()]);\n' +       '+  }\n' +       '+\n' +       '+  const reviews: string[] = [];\n' +       '+  for await (const m of messages) {\n' +       '+    const reviewChunk = await completionRequest(m, verbose);\n' +       '+    if (reviewChunk) {\n' +       '+      reviews.push(reviewChunk);\n' +       '+    }\n' +       '+  }\n' +       '+  if (reviews.length === 0) {\n' +       "+    console.error('No reviews were generated.');\n" +       '+    return undefined;\n' +       '+  }\n' +       '+\n' +       "+  if (verbose) console.info('reviews:', reviews.join('\\n'));\n" +       '+  return reviews;\n' +       '+}\n' +       '+\n' +       '+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {\n' +       '+  // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n' +       '+  // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n' +       '+  // limits include the token count from both the message array sent and the\n' +       '+  // model response. The number of tokens in the messages array combined\n' +       '+  // with the value of the max_tokens parameter must stay under these limits\n' +       "+  // or you'll receive an error. Therefore, we need to split the diff into\n" +       '+  // a separet review requests and then combine them into a single review.\n' +       '+  const reviews = await requestReviews(gitDetails, verbose);\n' +       '+  if (!reviews) return undefined;\n' +       '+\n' +       "+  const summaryTask = createSummaryTask(reviews.join('---\\n'));\n" +       '+  return await completionRequest([summarySystemMessage, summaryTask], verbose);\n' +       '+}\n' +       '\n' +       '-----\n' +       '\n' +       'Do not provide feedback yet. I will follow-up additional diff in a new message.\n'   },   {     role: 'user',     content: 'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters.'   } ] Sending request to OpenAI API... completion: {   status: 200,   statusText: 'OK',   headers: {     date: 'Wed, 10 May 2023 10:58:41 GMT',     'content-type': 'application/json',     'content-length': '786',     connection: 'close',     'access-control-allow-origin': '*',     'cache-control': 'no-cache, must-revalidate',     'openai-model': 'gpt-3.5-turbo-0301',     'openai-organization': 'user-qfbpcpzj0zasov0fwdnvlf7w',     'openai-processing-ms': '7933',     'openai-version': '2020-10-01',     'strict-transport-security': 'max-age=15724800; includeSubDomains',     'x-ratelimit-limit-requests': '3500',     'x-ratelimit-limit-tokens': '90000',     'x-ratelimit-remaining-requests': '3499',     'x-ratelimit-remaining-tokens': '88105',     'x-ratelimit-reset-requests': '17ms',     'x-ratelimit-reset-tokens': '1.263s',     'x-request-id': 'cee2c39922d390376a55f0b10574a31b',     'cf-cache-status': 'DYNAMIC',     server: 'cloudflare',     'cf-ray': '7c51aaf02df52f71-LAX',     'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'   },   config: {     transitional: {       silentJSONParsing: true,       forcedJSONParsing: true,       clarifyTimeoutError: false     },     adapter: [Function: httpAdapter],     transformRequest: [ [Function: transformRequest] ],     transformResponse: [ [Function: transformResponse] ],     timeout: 0,     xsrfCookieName: 'XSRF-TOKEN',     xsrfHeaderName: 'X-XSRF-TOKEN',     maxContentLength: -1,     maxBodyLength: -1,     validateStatus: [Function: validateStatus],     headers: {       Accept: 'application/json, text/plain, */*',       'Content-Type': 'application/json',       'User-Agent': 'OpenAI/NodeJS/3.2.1',       Authorization: 'Bearer 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',       'Content-Length': 7884     },     method: 'post',     data: '{"model":"gpt-3.5-turbo","messages":[{"role":"system","content":"You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves."},{"role":"user","content":"The change has the following title: refactor: Split review task into chunks to avoid token limit.\\n\\n  Your task is:\\n  - Review code changes and provide feedback:\\n  - Check for bugs and highlight them.\\n  - Verify alignment with commit messages.\\n  - Sort issues from major to minor.\\n  - Ensure adherence to best practices and project guidelines:\\n  - Code readability, maintainability, and documentation.\\n  - Consistent naming conventions and coding style.\\n  - Modular and organized functions and classes.\\n  - Analyze performance and optimization:\\n  - Identify potential performance bottlenecks.\\n  - Suggest optimizations or efficient algorithms.\\n  - Assess test coverage and quality:\\n  - Confirm appropriate unit tests are added or updated.\\n  - Check for untested edge cases.\\n  - Determine if integration tests are needed.\\n  - Evaluate code reusability:\\n  - Encourage use of existing libraries, frameworks, or code snippets.\\n  - Identify opportunities for reusable components or patterns.\\n  - Confirm cross-browser and cross-platform compatibility:\\n  - Provide security recommendations, if applicable.\\n  - Check the commit message for clear descriptions of changes.\\n  - Provide feedback as the numbered list.\\n  - focus only on negative parts.\\n\\n  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\\n  "},{"role":"user","content":"A description was given to help you assist in understand why these changes were made:\\n-----\\nTo accommodate the token limits for various GPT models:\\n- gpt-35-turbo: 4096 tokens\\n- gpt-4: 8192 tokens\\n- gpt-4-32k: 32768 tokens\\n\\nThese limits include tokens from both the message array and model\\nresponse. The combined token count of the messages array and max_tokens\\nparameter must stay within these limits to avoid errors.\\n\\nTo address this, we:\\n- Split the diff into separate review requests\\n- Combine the individual requests into a single review\\n\\n\\n-----\\nDo not provide feedback yet. I will follow-up with a diff of the change in a new message.\\n"},{"role":"user","content":"\\n-----\\ndiff --git a/src/review.ts b/src/review.ts\\nindex 7f7d295..763a778 100644\\n--- a/src/review.ts\\n+++ b/src/review.ts\\n@@ -25,13 +25,13 @@ const configuration = new Configuration({\\n \\n const openai = new OpenAIApi(configuration);\\n \\n-const systemMessage: ChatCompletionRequestMessage = {\\n+const reviewSystemMessage: ChatCompletionRequestMessage = {\\n   role: \'system\',\\n   content:\\n     \'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.\',\\n };\\n \\n-function createTaskMessage(title: string): ChatCompletionRequestMessage {\\n+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {\\n   const content = The change has the following title: ${title}.\n \n   Your task is:\n@@ -115,32 +115,43 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {\n   };\n }\n \n+const summarySystemMessage: ChatCompletionRequestMessage = {\n+  role: 'system',\n+  content:\n+    'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',\n+};\n+\n+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {\n+  const content = \\n+  Your task is:\\n+  - To make a summary of the reviews that are provided to the same code change.\\n+  - Those reviews are on the different git diffs of the same git patch or pull request.\\n+\\n+  -----\\n+  ${reviewChunk.slice(0, MAX_CONTENT_SIZE)}\\n+  -----\\n+\\n+  Make a summary of the reviews as the bullet points.\\n+  ;\n+\n+  return {\n+    role: 'user',\n+    content,\n+  };\n+}\n+\n export function logContext(gitDetails: GitDetails) {\n-  console.info(systemMessage.content);\n-  console.info(createTaskMessage(gitDetails.title));\n+  console.info(reviewSystemMessage.content);\n+  console.info(createReviewTaskMessage(gitDetails.title));\n   console.info(createDescriptionMessage(gitDetails.description).content);\n   console.info(createDiffMessage(gitDetails.diff).content);\n }\n \n-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {\n-  if (verbose) logContext(gitDetails);\n-\n+async function completionRequest(\n+  messages: ChatCompletionRequestMessage[],\n+  verbose: boolean,\n+): Promise<string | undefined> {\n   try {\n-    const messages = [\n-      systemMessage,\n-      createTaskMessage(gitDetails.title),\n-      createDescriptionMessage(gitDetails.description),\n-      // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n-      // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n-      // limits include the token count from both the message array sent and the\n-      // model response. The number of tokens in the messages array combined\n-      // with the value of the max_tokens parameter must stay under these limits\n-      // or you'll receive an error.\n-      // TODO: combine into several requests if diff is too big\n-      ...splitDiff(gitDetails.diff).slice(0, 1),\n-      commandToExecuteTheTask(),\n-    ];\n-\n     if (verbose) console.info('Messages:', messages);\n     if (verbose) console.info('Sending request to OpenAI API...');\n \n@@ -157,3 +168,49 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri\n     return undefined;\n   }\n }\n+\n+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {\n+  if (verbose) logContext(gitDetails);\n+\n+  const diffs = splitDiff(gitDetails.diff);\n+  const baseMessage = [\n+    reviewSystemMessage,\n+    createReviewTaskMessage(gitDetails.title),\n+    createDescriptionMessage(gitDetails.description),\n+  ];\n+\n+  const messages: ChatCompletionRequestMessage[][] = [];\n+  for (const d of diffs) {\n+    messages.push([...baseMessage, d, commandToExecuteTheTask()]);\n+  }\n+\n+  const reviews: string[] = [];\n+  for await (const m of messages) {\n+    const reviewChunk = await completionRequest(m, verbose);\n+    if (reviewChunk) {\n+      reviews.push(reviewChunk);\n+    }\n+  }\n+  if (reviews.length === 0) {\n+    console.error('No reviews were generated.');\n+    return undefined;\n+  }\n+\n+  if (verbose) console.info('reviews:', reviews.join('\\n'));\n+  return reviews;\n+}\n+\n+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {\n+  // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n+  // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n+  // limits include the token count from both the message array sent and the\n+  // model response. The number of tokens in the messages array combined\n+  // with the value of the max_tokens parameter must stay under these limits\n+  // or you'll receive an error. Therefore, we need to split the diff into\n+  // a separet review requests and then combine them into a single review.\n+  const reviews = await requestReviews(gitDetails, verbose);\n+  if (!reviews) return undefined;\n+\n+  const summaryTask = createSummaryTask(reviews.join('---\\n'));\n+  return await completionRequest([summarySystemMessage, summaryTask], verbose);\n+}\n\n-----\n\nDo not provide feedback yet. I will follow-up additional diff in a new message.\n"},{"role":"user","content":"All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters."}],"temperature":0.7}',
url: 'https://api.openai.com/v1/chat/completions'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
finish: [Function: requestOnFinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 7884,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'api.openai.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.openai.com',
_closeAfterHandlingError: false,
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 8,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kSetNoDelay)]: false,
[Symbol(kSetKeepAlive)]: true,
[Symbol(kSetKeepAliveInitialDelay)]: 60,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'POST /v1/chat/completions HTTP/1.1\r\n' +
'Accept: application/json, text/plain, /\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: OpenAI/NodeJS/3.2.1\r\n' +
'Authorization: Bearer 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\r\n' +
'Content-Length: 7884\r\n' +
'Host: api.openai.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype],
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/v1/chat/completions',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
joinDuplicateHeaders: undefined,
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 200,
statusMessage: 'OK',
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://api.openai.com/v1/chat/completions',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 44,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.openai.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 7884,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular 1],
_currentUrl: 'https://api.openai.com/v1/chat/completions',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'user-agent': [Array],
authorization: [Array],
'content-length': [Array],
host: [Array]
},
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
data: {
id: 'chatcmpl-7EbogLrUG5iC1qQHrcZmln8ZNCxK1',
object: 'chat.completion',
created:<PHONE_NUMBER>,
model: 'gpt-3.5-turbo-0301',
usage: { prompt_tokens: 1782, completion_tokens: 93, total_tokens: 1875 },
choices: [ [Object] ]
}
}
reviews: Code changes are well-structured and documented, following best practices, modular and organized. Splitting the diff into separate review requests and combining the individual requests into a single review is an efficient way of avoiding token limit errors. The function createTaskMessage is now createReviewTaskMessage to match its purpose. Code is readable and maintainable. Tests are needed to cover untested edge cases and ensure code quality. The commit message is clear and descriptive.
Messages: [
{
role: 'system',
content: 'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.'
},
{
role: 'user',
content: '\n' +
'  Your task is:\n' +
'  - To make a summary of the reviews that are provided to the same code change.\n' +
'  - Those reviews are on the different git diffs of the same git patch or pull request.\n' +
'\n' +
'  -----\n' +
'  Code changes are well-structured and documented, following best practices, modular and organized. Splitting the diff into separate review requests and combining the individual requests into a single review is an efficient way of avoiding token limit errors. The function createTaskMessage is now createReviewTaskMessage to match its purpose. Code is readable and maintainable. Tests are needed to cover untested edge cases and ensure code quality. The commit message is clear and descriptive.\n' +
'  -----\n' +
'\n' +
'  Make a summary of the reviews as the bullet points.\n' +
'  '
}
]
Sending request to OpenAI API...
completion: {
status: 200,
statusText: 'OK',
headers: {
date: 'Wed, 10 May 2023 10:58:48 GMT',
'content-type': 'application/json',
'content-length': '771',
connection: 'close',
'access-control-allow-origin': '',
'cache-control': 'no-cache, must-revalidate',
'openai-model': 'gpt-3.5-turbo-0301',
'openai-organization': 'user-qfbpcpzj0zasov0fwdnvlf7w',
'openai-processing-ms': '7016',
'openai-version': '2020-10-01',
'strict-transport-security': 'max-age=15724800; includeSubDomains',
'x-ratelimit-limit-requests': '3500',
'x-ratelimit-limit-tokens': '90000',
'x-ratelimit-remaining-requests': '3499',
'x-ratelimit-remaining-tokens': '89754',
'x-ratelimit-reset-requests': '17ms',
'x-ratelimit-reset-tokens': '164ms',
'x-request-id': '55c3963819d937ce39f9de42df3f9e45',
'cf-cache-status': 'DYNAMIC',
server: 'cloudflare',
'cf-ray': '7c51ab22e9212a91-LAX',
'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'
},
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, /',
'Content-Type': 'application/json',
'User-Agent': 'OpenAI/NodeJS/3.2.1',
Authorization: 'Bearer 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',
'Content-Length': 1038
},
method: 'post',
data: '{"model":"gpt-3.5-turbo","messages":[{"role":"system","content":"You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves."},{"role":"user","content":"\n  Your task is:\n  - To make a summary of the reviews that are provided to the same code change.\n  - Those reviews are on the different git diffs of the same git patch or pull request.\n\n  -----\n  Code changes are well-structured and documented, following best practices, modular and organized. Splitting the diff into separate review requests and combining the individual requests into a single review is an efficient way of avoiding token limit errors. The function createTaskMessage is now createReviewTaskMessage to match its purpose. Code is readable and maintainable. Tests are needed to cover untested edge cases and ensure code quality. The commit message is clear and descriptive.\n  -----\n\n  Make a summary of the reviews as the bullet points.\n  "}],"temperature":0.7}',
url: 'https://api.openai.com/v1/chat/completions'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
finish: [Function: requestOnFinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 1038,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'api.openai.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.openai.com',
_closeAfterHandlingError: false,
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 28,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kSetNoDelay)]: false,
[Symbol(kSetKeepAlive)]: true,
[Symbol(kSetKeepAliveInitialDelay)]: 60,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'POST /v1/chat/completions HTTP/1.1\r\n' +
'Accept: application/json, text/plain, /\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: OpenAI/NodeJS/3.2.1\r\n' +
'Authorization: Bearer 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\r\n' +
'Content-Length: 1038\r\n' +
'Host: api.openai.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype],
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/v1/chat/completions',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
joinDuplicateHeaders: undefined,
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 200,
statusMessage: 'OK',
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://api.openai.com/v1/chat/completions',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 44,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.openai.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 1038,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://api.openai.com/v1/chat/completions',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'user-agent': [Array],
authorization: [Array],
'content-length': [Array],
host: [Array]
},
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
data: {
id: 'chatcmpl-7EboonPBXYTbLBiRe71IicrYg7Cze',
object: 'chat.completion',
created:<PHONE_NUMBER>,
model: 'gpt-3.5-turbo-0301',
usage: { prompt_tokens: 197, completion_tokens: 97, total_tokens: 294 },
choices: [ [Object] ]
}
}
Review task completed!

Code changes are well-structured and documented.
Best practices are followed in the code organization and modularity.
Splitting the diff into separate review requests is an efficient way to avoid token limit errors.
The function createTaskMessage is renamed to createReviewTaskMessage to match its purpose.
The code is readable and maintainable.
Need for tests to cover untested edge cases and ensure code quality.
The commit message is clear and descriptive.

 Provide feedback on the code changes given. Do not introduce yourselves.
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code, give feedback\n' +
'  - Find, prioritize bugs\n' +
'  - Ensure commit message alignment\n' +
'  - Follow best practices, guidelines:\n' +
'  - Readability, maintainability, docs\n' +
'  - No scope creep\n' +
'  - Consistent naming, style\n' +
'  - Modular organization\n' +
'  - Review performance, optimization:\n' +
'  - Spot bottlenecks\n' +
'  - Propose improvements\n' +
'  - Examine test coverage:\n' +
'  - Verify unit tests\n' +
'  - Identify edge cases\n' +
'  - Assess integration needs\n' +
'  - Assess reusability:\n' +
'  - Leverage existing resources\n' +
'  - Spot reusable components\n' +
'  - Confirm compatibility, security\n' +
'  - Clarify commit messages\n' +
'  - List negative feedback only\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
}
A description was given to help you assist in understand why these changes were made:
To accommodate the token limits for various GPT models:

gpt-35-turbo: 4096 tokens
gpt-4: 8192 tokens
gpt-4-32k: 32768 tokens

These limits include tokens from both the message array and model
response. The combined token count of the messages array and max_tokens
parameter must stay within these limits to avoid errors.
To address this, we:

Split the diff into separate review requests
Combine the individual requests into a single review

Do not provide feedback yet. I will follow-up with a diff of the change in a new message.

diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index bdaa15d..b66e6a1 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -38,7 +38,7 @@ jobs:
script: |
const fs = require('fs');
const filePath = 'review.txt';

       const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(3,-2).join('\n');

       const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(2,-2).join('\n');
       const output = `**Automatic review for commit ${{ github.event.pull_request.head.sha || github.sha }}:**\n${fileContents}`;
       await github.issues.createComment({
         owner: context.repo.owner,

diff --git a/src/index.ts b/src/index.ts
index faff329..95f5af8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -19,6 +19,7 @@ if (gitDetails instanceof Error) {
job(gitDetails)
.then((review: string | undefined) => {
if (!review) {

 console.log('Review task failed!');
 throw new Error('Review task failed');

}

diff --git a/src/review.ts b/src/review.ts
index 7f7d295..4e99c58 100644
--- a/src/review.ts
+++ b/src/review.ts
@@ -25,39 +25,37 @@ const configuration = new Configuration({
const openai = new OpenAIApi(configuration);
-const systemMessage: ChatCompletionRequestMessage = {
+const reviewSystemMessage: ChatCompletionRequestMessage = {
role: 'system',
content:
'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',
};
-function createTaskMessage(title: string): ChatCompletionRequestMessage {
+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {
const content = `The change has the following title: ${title}.
Your task is:

Review code changes and provide feedback:

Check for bugs and highlight them.

Verify alignment with commit messages.

Sort issues from major to minor.

Ensure adherence to best practices and project guidelines:

Code readability, maintainability, and documentation.

Consistent naming conventions and coding style.

Modular and organized functions and classes.

Analyze performance and optimization:

Identify potential performance bottlenecks.

Suggest optimizations or efficient algorithms.

Assess test coverage and quality:

Confirm appropriate unit tests are added or updated.

Check for untested edge cases.

Determine if integration tests are needed.

Evaluate code reusability:

Encourage use of existing libraries, frameworks, or code snippets.

Identify opportunities for reusable components or patterns.

Confirm cross-browser and cross-platform compatibility:

Provide security recommendations, if applicable.

Check the commit message for clear descriptions of changes.

Provide feedback as the numbered list.

focus only on negative parts.

Review code, give feedback

Find, prioritize bugs

Ensure commit message alignment

Follow best practices, guidelines:

Readability, maintainability, docs

No scope creep

Consistent naming, style

Modular organization

Review performance, optimization:

Spot bottlenecks

Propose improvements

Examine test coverage:

Verify unit tests

Identify edge cases

Assess integration needs

Assess reusability:

Leverage existing resources

Spot reusable components

Confirm compatibility, security

Clarify commit messages

List negative feedback only

Do not provide feedback yet. I will follow-up with a description of the change in a new message.
`;
@@ -108,7 +106,32 @@ Do not provide feedback yet. I will follow-up additional diff in a new message.

function commandToExecuteTheTask(): ChatCompletionRequestMessage {
const content =

'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters.';

'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.';
return {
role: 'user',
content,
};
+}

+const summarySystemMessage: ChatCompletionRequestMessage = {

role: 'system',
content:
'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',
+};

+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {

const content = `
Your task is:

To make a summary of the reviews that are provided to the same code change.

Those reviews are on the different git diffs of the same git patch or pull request.

${reviewChunk.slice(0, MAX_CONTENT_SIZE)}

Make a summary of the reviews as the bullet points.
`;
return {
role: 'user',
content,
@@ -116,31 +139,17 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {
}

export function logContext(gitDetails: GitDetails) {

console.info(systemMessage.content);
console.info(createTaskMessage(gitDetails.title));

console.info(reviewSystemMessage.content);
console.info(createReviewTaskMessage(gitDetails.title));
console.info(createDescriptionMessage(gitDetails.description).content);
console.info(createDiffMessage(gitDetails.diff).content);
}

-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {

if (verbose) logContext(gitDetails);

+async function completionRequest(

messages: ChatCompletionRequestMessage[],
verbose: boolean,
+): Promise<string | undefined> {
try {

const messages = [

 systemMessage,

 createTaskMessage(gitDetails.title),

 createDescriptionMessage(gitDetails.description),

 // The token limit for gpt-35-turbo is 4096 tokens, whereas the token

 // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These

 // limits include the token count from both the message array sent and the

 // model response. The number of tokens in the messages array combined

 // with the value of the max_tokens parameter must stay under these limits

 // or you'll receive an error.

 // TODO: combine into several requests if diff is too big

 ...splitDiff(gitDetails.diff).slice(0, 1),

 commandToExecuteTheTask(),

];
if (verbose) console.info('Messages:', messages);
if (verbose) console.info('Sending request to OpenAI API...');

@@ -150,10 +159,58 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri
temperature: TEMPERATURE,
});

if (verbose) console.info('completion:', completion);
return completion.data.choices[0]?.message?.content;
} catch (error) {
console.error('Error while calling OpenAI API:', error);
return undefined;
}
}

+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {

if (verbose) logContext(gitDetails);

const diffs = splitDiff(gitDetails.diff);
const baseMessage = [
reviewSystemMessage,
createReviewTaskMessage(gitDetails.title),
createDescriptionMessage(gitDetails.description),
];

const messages: ChatCompletionRequestMessage[][] = [];
for (const d of diffs) {
messages.push([...baseMessage, d, commandToExecuteTheTask()]);
}

const reviews: string[] = [];
for await (const m of messages) {
const reviewChunk = await completionRequest(m, verbose);
if (reviewChunk) {

 reviews.push(reviewChunk);

}
}
if (reviews.length === 0) {
console.error('No reviews were generated.');
return undefined;
}

if (verbose) console.info('reviews:', reviews.join('\n'));
return reviews;
+}

+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {

// The token limit for gpt-35-turbo is 4096 tokens, whereas the token
// limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These
// limits include the token count from both the message array sent and the
// model response. The number of tokens in the messages array combined
// with the value of the max_tokens parameter must stay under these limits
// or you'll receive an error. Therefore, we need to split the diff into
// a separet review requests and then combine them into a single review.
const reviews = await requestReviews(gitDetails, verbose);
if (!reviews) {
console.error('No reviews were generated.');
throw new Error('No reviews were generated.');
}

const summaryTask = createSummaryTask(reviews.join('---\n'));
return await completionRequest([summarySystemMessage, summaryTask], verbose);
+}

Do not provide feedback yet. I will follow-up additional diff in a new message.
Messages: [
{
role: 'system',
content: 'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.'
},
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code, give feedback\n' +
'  - Find, prioritize bugs\n' +
'  - Ensure commit message alignment\n' +
'  - Follow best practices, guidelines:\n' +
'  - Readability, maintainability, docs\n' +
'  - No scope creep\n' +
'  - Consistent naming, style\n' +
'  - Modular organization\n' +
'  - Review performance, optimization:\n' +
'  - Spot bottlenecks\n' +
'  - Propose improvements\n' +
'  - Examine test coverage:\n' +
'  - Verify unit tests\n' +
'  - Identify edge cases\n' +
'  - Assess integration needs\n' +
'  - Assess reusability:\n' +
'  - Leverage existing resources\n' +
'  - Spot reusable components\n' +
'  - Confirm compatibility, security\n' +
'  - Clarify commit messages\n' +
'  - List negative feedback only\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
},
{
role: 'user',
content: 'A description was given to help you assist in understand why these changes were made:\n' +
'-----\n' +
'To accommodate the token limits for various GPT models:\n' +
'- gpt-35-turbo: 4096 tokens\n' +
'- gpt-4: 8192 tokens\n' +
'- gpt-4-32k: 32768 tokens\n' +
'\n' +
'These limits include tokens from both the message array and model\n' +
'response. The combined token count of the messages array and max_tokens\n' +
'parameter must stay within these limits to avoid errors.\n' +
'\n' +
'To address this, we:\n' +
'- Split the diff into separate review requests\n' +
'- Combine the individual requests into a single review\n' +
'\n' +
'\n' +
'-----\n' +
'Do not provide feedback yet. I will follow-up with a diff of the change in a new message.\n'
},
{
role: 'user',
content: '\n' +
'-----\n' +
'diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml\n' +
'index bdaa15d..b66e6a1 100644\n' +
'--- a/.github/workflows/pr.yml\n' +
'+++ b/.github/workflows/pr.yml\n' +
'@@ -38,7 +38,7 @@ jobs:\n' +
'           script: |\n' +
"             const fs = require('fs');\n" +
"             const filePath = 'review.txt';\n" +
"-            const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(3,-2).join('\n');\n" +
"+            const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(2,-2).join('\n');\n" +
'             const output = **Automatic review for commit ${{ github.event.pull_request.head.sha || github.sha }}:**\\n${fileContents};\n' +
'             await github.issues.createComment({\n' +
'               owner: context.repo.owner,\n' +
'diff --git a/src/index.ts b/src/index.ts\n' +
'index faff329..95f5af8 100644\n' +
'--- a/src/index.ts\n' +
'+++ b/src/index.ts\n' +
'@@ -19,6 +19,7 @@ if (gitDetails instanceof Error) {\n' +
' job(gitDetails)\n' +
'   .then((review: string | undefined) => {\n' +
'     if (!review) {\n' +
"+      console.log('Review task failed!');\n" +
"       throw new Error('Review task failed');\n" +
'     }\n' +
' \n' +
'diff --git a/src/review.ts b/src/review.ts\n' +
'index 7f7d295..4e99c58 100644\n' +
'--- a/src/review.ts\n' +
'+++ b/src/review.ts\n' +
'@@ -25,39 +25,37 @@ const configuration = new Configuration({\n' +
' \n' +
' const openai = new OpenAIApi(configuration);\n' +
' \n' +
'-const systemMessage: ChatCompletionRequestMessage = {\n' +
'+const reviewSystemMessage: ChatCompletionRequestMessage = {\n' +
"   role: 'system',\n" +
'   content:\n' +
"     'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',\n" +
' };\n' +
' \n' +
'-function createTaskMessage(title: string): ChatCompletionRequestMessage {\n' +
'+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {\n' +
'   const content = The change has the following title: ${title}.\n' +       ' \n' +       '   Your task is:\n' +       '-  - Review code changes and provide feedback:\n' +       '-  - Check for bugs and highlight them.\n' +       '-  - Verify alignment with commit messages.\n' +       '-  - Sort issues from major to minor.\n' +       '-  - Ensure adherence to best practices and project guidelines:\n' +       '-  - Code readability, maintainability, and documentation.\n' +       '-  - Consistent naming conventions and coding style.\n' +       '-  - Modular and organized functions and classes.\n' +       '-  - Analyze performance and optimization:\n' +       '-  - Identify potential performance bottlenecks.\n' +       '-  - Suggest optimizations or efficient algorithms.\n' +       '-  - Assess test coverage and quality:\n' +       '-  - Confirm appropriate unit tests are added or updated.\n' +       '-  - Check for untested edge cases.\n' +       '-  - Determine if integration tests are needed.\n' +       '-  - Evaluate code reusability:\n' +       '-  - Encourage use of existing libraries, frameworks, or code snippets.\n' +       '-  - Identify opportunities for reusable components or patterns.\n' +       '-  - Confirm cross-browser and cross-platform compatibility:\n' +       '-  - Provide security recommendations, if applicable.\n' +       '-  - Check the commit message for clear descriptions of changes.\n' +       '-  - Provide feedback as the numbered list.\n' +       '-  - focus only on negative parts.\n' +       '+  - Review code, give feedback\n' +       '+  - Find, prioritize bugs\n' +       '+  - Ensure commit message alignment\n' +       '+  - Follow best practices, guidelines:\n' +       '+  - Readability, maintainability, docs\n' +       '+  - No scope creep\n' +       '+  - Consistent naming, style\n' +       '+  - Modular organization\n' +       '+  - Review performance, optimization:\n' +       '+  - Spot bottlenecks\n' +       '+  - Propose improvements\n' +       '+  - Examine test coverage:\n' +       '+  - Verify unit tests\n' +       '+  - Identify edge cases\n' +       '+  - Assess integration needs\n' +       '+  - Assess reusability:\n' +       '+  - Leverage existing resources\n' +       '+  - Spot reusable components\n' +       '+  - Confirm compatibility, security\n' +       '+  - Clarify commit messages\n' +       '+  - List negative feedback only\n' +       ' \n' +       '   Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +       '   ;\n' +
'@@ -108,7 +106,32 @@ Do not provide feedback yet. I will follow-up additional diff in a new message.\n' +
' \n' +
' function commandToExecuteTheTask(): ChatCompletionRequestMessage {\n' +
'   const content =\n' +
"-    'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters.';\n" +
"+    'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.';\n" +
'+  return {\n' +
"+    role: 'user',\n" +
'+    content,\n' +
'+  };\n' +
'+}\n' +
'+\n' +
'+const summarySystemMessage: ChatCompletionRequestMessage = {\n' +
"+  role: 'system',\n" +
'+  content:\n' +
"+    'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',\n" +
'+};\n' +
'+\n' +
'+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {\n' +
'+  const content = \n' +       '+  Your task is:\n' +       '+  - To make a summary of the reviews that are provided to the same code change.\n' +       '+  - Those reviews are on the different git diffs of the same git patch or pull request.\n' +       '+\n' +       '+  -----\n' +       '+  ${reviewChunk.slice(0, MAX_CONTENT_SIZE)}\n' +       '+  -----\n' +       '+\n' +       '+  Make a summary of the reviews as the bullet points.\n' +       '+  ;\n' +
'+\n' +
'   return {\n' +
"     role: 'user',\n" +
'     content,\n' +
'@@ -116,31 +139,17 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {\n' +
' }\n' +
' \n' +
' export function logContext(gitDetails: GitDetails) {\n' +
'-  console.info(systemMessage.content);\n' +
'-  console.info(createTaskMessage(gitDetails.title));\n' +
'+  console.info(reviewSystemMessage.content);\n' +
'+  console.info(createReviewTaskMessage(gitDetails.title));\n' +
'   console.info(createDescriptionMessage(gitDetails.description).content);\n' +
'   console.info(createDiffMessage(gitDetails.diff).content);\n' +
' }\n' +
' \n' +
'-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {\n' +
'-  if (verbose) logContext(gitDetails);\n' +
'-\n' +
'+async function completionRequest(\n' +
'+  messages: ChatCompletionRequestMessage[],\n' +
'+  verbose: boolean,\n' +
'+): Promise<string | undefined> {\n' +
'   try {\n' +
'-    const messages = [\n' +
'-      systemMessage,\n' +
'-      createTaskMessage(gitDetails.title),\n' +
'-      createDescriptionMessage(gitDetails.description),\n' +
'-      // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n' +
'-      // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n' +
'-      // limits include the token count from both the message array sent and the\n' +
'-      // model response. The number of tokens in the messages array combined\n' +
'-      // with the value of the max_tokens parameter must stay under these limits\n' +
"-      // or you'll receive an error.\n" +
'-      // TODO: combine into several requests if diff is too big\n' +
'-      ...splitDiff(gitDetails.diff).slice(0, 1),\n' +
'-      commandToExecuteTheTask(),\n' +
'-    ];\n' +
'-\n' +
"     if (verbose) console.info('Messages:', messages);\n" +
"     if (verbose) console.info('Sending request to OpenAI API...');\n" +
' \n' +
'@@ -150,10 +159,58 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri\n' +
'       temperature: TEMPERATURE,\n' +
'     });\n' +
' \n' +
"-    if (verbose) console.info('completion:', completion);\n" +
'     return completion.data.choices[0]?.message?.content;\n' +
'   } catch (error) {\n' +
"     console.error('Error while calling OpenAI API:', error);\n" +
'     return undefined;\n' +
'   }\n' +
' }\n' +
'+\n' +
'+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {\n' +
'+  if (verbose) logContext(gitDetails);\n' +
'+\n' +
'+  const diffs = splitDiff(gitDetails.diff);\n' +
'+  const baseMessage = [\n' +
'+    reviewSystemMessage,\n' +
'+    createReviewTaskMessage(gitDetails.title),\n' +
'+    createDescriptionMessage(gitDetails.description),\n' +
'+  ];\n' +
'+\n' +
'+  const messages: ChatCompletionRequestMessage[][] = [];\n' +
'+  for (const d of diffs) {\n' +
'+    messages.push([...baseMessage, d, commandToExecuteTheTask()]);\n' +
'+  }\n' +
'+\n' +
'+  const reviews: string[] = [];\n' +
'+  for await (const m of messages) {\n' +
'+    const reviewChunk = await completionRequest(m, verbose);\n' +
'+    if (reviewChunk) {\n' +
'+      reviews.push(reviewChunk);\n' +
'+    }\n' +
'+  }\n' +
'+  if (reviews.length === 0) {\n' +
"+    console.error('No reviews were generated.');\n" +
'+    return undefined;\n' +
'+  }\n' +
'+\n' +
"+  if (verbose) console.info('reviews:', reviews.join('\n'));\n" +
'+  return reviews;\n' +
'+}\n' +
'+\n' +
'+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {\n' +
'+  // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n' +
'+  // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n' +
'+  // limits include the token count from both the message array sent and the\n' +
'+  // model response. The number of tokens in the messages array combined\n' +
'+  // with the value of the max_tokens parameter must stay under these limits\n' +
"+  // or you'll receive an error. Therefore, we need to split the diff into\n" +
'+  // a separet review requests and then combine them into a single review.\n' +
'+  const reviews = await requestReviews(gitDetails, verbose);\n' +
'+  if (!reviews) {\n' +
"+    console.error('No reviews were generated.');\n" +
"+    throw new Error('No reviews were generated.');\n" +
'+  }\n' +
'+\n' +
"+  const summaryTask = createSummaryTask(reviews.join('---\n'));\n" +
'+  return await completionRequest([summarySystemMessage, summaryTask], verbose);\n' +
'+}\n' +
'\n' +
'-----\n' +
'\n' +
'Do not provide feedback yet. I will follow-up additional diff in a new message.\n'
},
{
role: 'user',
content: 'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.'
}
]
Sending request to OpenAI API...

Automatic review for commit 561a75ad77b1540b4b9e858fc802b477cf7f7bb7:
You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code, give feedback\n' +
'  - Find, prioritize bugs\n' +
'  - Ensure commit message alignment\n' +
'  - Follow best practices, guidelines:\n' +
'  - Readability, maintainability, docs\n' +
'  - No scope creep\n' +
'  - Consistent naming, style\n' +
'  - Modular organization\n' +
'  - Review performance, optimization:\n' +
'  - Spot bottlenecks\n' +
'  - Propose improvements\n' +
'  - Examine test coverage:\n' +
'  - Verify unit tests\n' +
'  - Identify edge cases\n' +
'  - Assess integration needs\n' +
'  - Assess reusability:\n' +
'  - Leverage existing resources\n' +
'  - Spot reusable components\n' +
'  - Confirm compatibility, security\n' +
'  - Clarify commit messages\n' +
'  - List negative feedback only\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
}
A description was given to help you assist in understand why these changes were made:
To accommodate the token limits for various GPT models:

gpt-35-turbo: 4096 tokens
gpt-4: 8192 tokens
gpt-4-32k: 32768 tokens

These limits include tokens from both the message array and model
response. The combined token count of the messages array and max_tokens
parameter must stay within these limits to avoid errors.
To address this, we:

Split the diff into separate review requests
Combine the individual requests into a single review

Do not provide feedback yet. I will follow-up with a diff of the change in a new message.

diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index bdaa15d..b66e6a1 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -38,7 +38,7 @@ jobs:
script: |
const fs = require('fs');
const filePath = 'review.txt';

       const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(3,-2).join('\n');

       const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(2,-2).join('\n');
       const output = `**Automatic review for commit ${{ github.event.pull_request.head.sha || github.sha }}:**\n${fileContents}`;
       await github.issues.createComment({
         owner: context.repo.owner,

diff --git a/src/index.ts b/src/index.ts
index faff329..95f5af8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -19,6 +19,7 @@ if (gitDetails instanceof Error) {
job(gitDetails)
.then((review: string | undefined) => {
if (!review) {

 console.log('Review task failed!');
 throw new Error('Review task failed');

}

diff --git a/src/review.ts b/src/review.ts
index 7f7d295..4e99c58 100644
--- a/src/review.ts
+++ b/src/review.ts
@@ -25,39 +25,37 @@ const configuration = new Configuration({
const openai = new OpenAIApi(configuration);
-const systemMessage: ChatCompletionRequestMessage = {
+const reviewSystemMessage: ChatCompletionRequestMessage = {
role: 'system',
content:
'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',
};
-function createTaskMessage(title: string): ChatCompletionRequestMessage {
+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {
const content = `The change has the following title: ${title}.
Your task is:

Review code changes and provide feedback:

Check for bugs and highlight them.

Verify alignment with commit messages.

Sort issues from major to minor.

Ensure adherence to best practices and project guidelines:

Code readability, maintainability, and documentation.

Consistent naming conventions and coding style.

Modular and organized functions and classes.

Analyze performance and optimization:

Identify potential performance bottlenecks.

Suggest optimizations or efficient algorithms.

Assess test coverage and quality:

Confirm appropriate unit tests are added or updated.

Check for untested edge cases.

Determine if integration tests are needed.

Evaluate code reusability:

Encourage use of existing libraries, frameworks, or code snippets.

Identify opportunities for reusable components or patterns.

Confirm cross-browser and cross-platform compatibility:

Provide security recommendations, if applicable.

Check the commit message for clear descriptions of changes.

Provide feedback as the numbered list.

focus only on negative parts.

Review code, give feedback

Find, prioritize bugs

Ensure commit message alignment

Follow best practices, guidelines:

Readability, maintainability, docs

No scope creep

Consistent naming, style

Modular organization

Review performance, optimization:

Spot bottlenecks

Propose improvements

Examine test coverage:

Verify unit tests

Identify edge cases

Assess integration needs

Assess reusability:

Leverage existing resources

Spot reusable components

Confirm compatibility, security

Clarify commit messages

List negative feedback only

Do not provide feedback yet. I will follow-up with a description of the change in a new message.
`;
@@ -108,7 +106,32 @@ Do not provide feedback yet. I will follow-up additional diff in a new message.

function commandToExecuteTheTask(): ChatCompletionRequestMessage {
const content =

'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters.';

'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.';
return {
role: 'user',
content,
};
+}

+const summarySystemMessage: ChatCompletionRequestMessage = {

role: 'system',
content:
'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',
+};

+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {

const content = `
Your task is:

To make a summary of the reviews that are provided to the same code change.

Those reviews are on the different git diffs of the same git patch or pull request.

${reviewChunk.slice(0, MAX_CONTENT_SIZE)}

Make a summary of the reviews as the bullet points.
`;
return {
role: 'user',
content,
@@ -116,31 +139,17 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {
}

export function logContext(gitDetails: GitDetails) {

console.info(systemMessage.content);
console.info(createTaskMessage(gitDetails.title));

console.info(reviewSystemMessage.content);
console.info(createReviewTaskMessage(gitDetails.title));
console.info(createDescriptionMessage(gitDetails.description).content);
console.info(createDiffMessage(gitDetails.diff).content);
}

-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {

if (verbose) logContext(gitDetails);

+async function completionRequest(

messages: ChatCompletionRequestMessage[],
verbose: boolean,
+): Promise<string | undefined> {
try {

const messages = [

 systemMessage,

 createTaskMessage(gitDetails.title),

 createDescriptionMessage(gitDetails.description),

 // The token limit for gpt-35-turbo is 4096 tokens, whereas the token

 // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These

 // limits include the token count from both the message array sent and the

 // model response. The number of tokens in the messages array combined

 // with the value of the max_tokens parameter must stay under these limits

 // or you'll receive an error.

 // TODO: combine into several requests if diff is too big

 ...splitDiff(gitDetails.diff).slice(0, 1),

 commandToExecuteTheTask(),

];
if (verbose) console.info('Messages:', messages);
if (verbose) console.info('Sending request to OpenAI API...');

@@ -150,10 +159,58 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri
temperature: TEMPERATURE,
});

if (verbose) console.info('completion:', completion);
return completion.data.choices[0]?.message?.content;
} catch (error) {
console.error('Error while calling OpenAI API:', error);
return undefined;
}
}

+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {

if (verbose) logContext(gitDetails);

const diffs = splitDiff(gitDetails.diff);
const baseMessage = [
reviewSystemMessage,
createReviewTaskMessage(gitDetails.title),
createDescriptionMessage(gitDetails.description),
];

const messages: ChatCompletionRequestMessage[][] = [];
for (const d of diffs) {
messages.push([...baseMessage, d, commandToExecuteTheTask()]);
}

const reviews: string[] = [];
for await (const m of messages) {
const reviewChunk = await completionRequest(m, verbose);
if (reviewChunk) {

 reviews.push(reviewChunk);

}
}
if (reviews.length === 0) {
console.error('No reviews were generated.');
return undefined;
}

if (verbose) console.info('reviews:', reviews.join('\n'));
return reviews;
+}

+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {

// The token limit for gpt-35-turbo is 4096 tokens, whereas the token
// limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These
// limits include the token count from both the message array sent and the
// model response. The number of tokens in the messages array combined
// with the value of the max_tokens parameter must stay under these limits
// or you'll receive an error. Therefore, we need to split the diff into
// a separet review requests and then combine them into a single review.
const reviews = await requestReviews(gitDetails, verbose);
if (!reviews) {
console.error('No reviews were generated.');
throw new Error('No reviews were generated.');
}

const summaryTask = createSummaryTask(reviews.join('---\n'));
return await completionRequest([summarySystemMessage, summaryTask], verbose);
+}

Do not provide feedback yet. I will follow-up additional diff in a new message.
Messages: [
{
role: 'system',
content: 'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.'
},
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code, give feedback\n' +
'  - Find, prioritize bugs\n' +
'  - Ensure commit message alignment\n' +
'  - Follow best practices, guidelines:\n' +
'  - Readability, maintainability, docs\n' +
'  - No scope creep\n' +
'  - Consistent naming, style\n' +
'  - Modular organization\n' +
'  - Review performance, optimization:\n' +
'  - Spot bottlenecks\n' +
'  - Propose improvements\n' +
'  - Examine test coverage:\n' +
'  - Verify unit tests\n' +
'  - Identify edge cases\n' +
'  - Assess integration needs\n' +
'  - Assess reusability:\n' +
'  - Leverage existing resources\n' +
'  - Spot reusable components\n' +
'  - Confirm compatibility, security\n' +
'  - Clarify commit messages\n' +
'  - List negative feedback only\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
},
{
role: 'user',
content: 'A description was given to help you assist in understand why these changes were made:\n' +
'-----\n' +
'To accommodate the token limits for various GPT models:\n' +
'- gpt-35-turbo: 4096 tokens\n' +
'- gpt-4: 8192 tokens\n' +
'- gpt-4-32k: 32768 tokens\n' +
'\n' +
'These limits include tokens from both the message array and model\n' +
'response. The combined token count of the messages array and max_tokens\n' +
'parameter must stay within these limits to avoid errors.\n' +
'\n' +
'To address this, we:\n' +
'- Split the diff into separate review requests\n' +
'- Combine the individual requests into a single review\n' +
'\n' +
'\n' +
'-----\n' +
'Do not provide feedback yet. I will follow-up with a diff of the change in a new message.\n'
},
{
role: 'user',
content: '\n' +
'-----\n' +
'diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml\n' +
'index bdaa15d..b66e6a1 100644\n' +
'--- a/.github/workflows/pr.yml\n' +
'+++ b/.github/workflows/pr.yml\n' +
'@@ -38,7 +38,7 @@ jobs:\n' +
'           script: |\n' +
"             const fs = require('fs');\n" +
"             const filePath = 'review.txt';\n" +
"-            const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(3,-2).join('\n');\n" +
"+            const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(2,-2).join('\n');\n" +
'             const output = **Automatic review for commit ${{ github.event.pull_request.head.sha || github.sha }}:**\\n${fileContents};\n' +
'             await github.issues.createComment({\n' +
'               owner: context.repo.owner,\n' +
'diff --git a/src/index.ts b/src/index.ts\n' +
'index faff329..95f5af8 100644\n' +
'--- a/src/index.ts\n' +
'+++ b/src/index.ts\n' +
'@@ -19,6 +19,7 @@ if (gitDetails instanceof Error) {\n' +
' job(gitDetails)\n' +
'   .then((review: string | undefined) => {\n' +
'     if (!review) {\n' +
"+      console.log('Review task failed!');\n" +
"       throw new Error('Review task failed');\n" +
'     }\n' +
' \n' +
'diff --git a/src/review.ts b/src/review.ts\n' +
'index 7f7d295..4e99c58 100644\n' +
'--- a/src/review.ts\n' +
'+++ b/src/review.ts\n' +
'@@ -25,39 +25,37 @@ const configuration = new Configuration({\n' +
' \n' +
' const openai = new OpenAIApi(configuration);\n' +
' \n' +
'-const systemMessage: ChatCompletionRequestMessage = {\n' +
'+const reviewSystemMessage: ChatCompletionRequestMessage = {\n' +
"   role: 'system',\n" +
'   content:\n' +
"     'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',\n" +
' };\n' +
' \n' +
'-function createTaskMessage(title: string): ChatCompletionRequestMessage {\n' +
'+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {\n' +
'   const content = The change has the following title: ${title}.\n' +       ' \n' +       '   Your task is:\n' +       '-  - Review code changes and provide feedback:\n' +       '-  - Check for bugs and highlight them.\n' +       '-  - Verify alignment with commit messages.\n' +       '-  - Sort issues from major to minor.\n' +       '-  - Ensure adherence to best practices and project guidelines:\n' +       '-  - Code readability, maintainability, and documentation.\n' +       '-  - Consistent naming conventions and coding style.\n' +       '-  - Modular and organized functions and classes.\n' +       '-  - Analyze performance and optimization:\n' +       '-  - Identify potential performance bottlenecks.\n' +       '-  - Suggest optimizations or efficient algorithms.\n' +       '-  - Assess test coverage and quality:\n' +       '-  - Confirm appropriate unit tests are added or updated.\n' +       '-  - Check for untested edge cases.\n' +       '-  - Determine if integration tests are needed.\n' +       '-  - Evaluate code reusability:\n' +       '-  - Encourage use of existing libraries, frameworks, or code snippets.\n' +       '-  - Identify opportunities for reusable components or patterns.\n' +       '-  - Confirm cross-browser and cross-platform compatibility:\n' +       '-  - Provide security recommendations, if applicable.\n' +       '-  - Check the commit message for clear descriptions of changes.\n' +       '-  - Provide feedback as the numbered list.\n' +       '-  - focus only on negative parts.\n' +       '+  - Review code, give feedback\n' +       '+  - Find, prioritize bugs\n' +       '+  - Ensure commit message alignment\n' +       '+  - Follow best practices, guidelines:\n' +       '+  - Readability, maintainability, docs\n' +       '+  - No scope creep\n' +       '+  - Consistent naming, style\n' +       '+  - Modular organization\n' +       '+  - Review performance, optimization:\n' +       '+  - Spot bottlenecks\n' +       '+  - Propose improvements\n' +       '+  - Examine test coverage:\n' +       '+  - Verify unit tests\n' +       '+  - Identify edge cases\n' +       '+  - Assess integration needs\n' +       '+  - Assess reusability:\n' +       '+  - Leverage existing resources\n' +       '+  - Spot reusable components\n' +       '+  - Confirm compatibility, security\n' +       '+  - Clarify commit messages\n' +       '+  - List negative feedback only\n' +       ' \n' +       '   Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +       '   ;\n' +
'@@ -108,7 +106,32 @@ Do not provide feedback yet. I will follow-up additional diff in a new message.\n' +
' \n' +
' function commandToExecuteTheTask(): ChatCompletionRequestMessage {\n' +
'   const content =\n' +
"-    'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters.';\n" +
"+    'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.';\n" +
'+  return {\n' +
"+    role: 'user',\n" +
'+    content,\n' +
'+  };\n' +
'+}\n' +
'+\n' +
'+const summarySystemMessage: ChatCompletionRequestMessage = {\n' +
"+  role: 'system',\n" +
'+  content:\n' +
"+    'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.',\n" +
'+};\n' +
'+\n' +
'+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {\n' +
'+  const content = \n' +       '+  Your task is:\n' +       '+  - To make a summary of the reviews that are provided to the same code change.\n' +       '+  - Those reviews are on the different git diffs of the same git patch or pull request.\n' +       '+\n' +       '+  -----\n' +       '+  ${reviewChunk.slice(0, MAX_CONTENT_SIZE)}\n' +       '+  -----\n' +       '+\n' +       '+  Make a summary of the reviews as the bullet points.\n' +       '+  ;\n' +
'+\n' +
'   return {\n' +
"     role: 'user',\n" +
'     content,\n' +
'@@ -116,31 +139,17 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {\n' +
' }\n' +
' \n' +
' export function logContext(gitDetails: GitDetails) {\n' +
'-  console.info(systemMessage.content);\n' +
'-  console.info(createTaskMessage(gitDetails.title));\n' +
'+  console.info(reviewSystemMessage.content);\n' +
'+  console.info(createReviewTaskMessage(gitDetails.title));\n' +
'   console.info(createDescriptionMessage(gitDetails.description).content);\n' +
'   console.info(createDiffMessage(gitDetails.diff).content);\n' +
' }\n' +
' \n' +
'-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {\n' +
'-  if (verbose) logContext(gitDetails);\n' +
'-\n' +
'+async function completionRequest(\n' +
'+  messages: ChatCompletionRequestMessage[],\n' +
'+  verbose: boolean,\n' +
'+): Promise<string | undefined> {\n' +
'   try {\n' +
'-    const messages = [\n' +
'-      systemMessage,\n' +
'-      createTaskMessage(gitDetails.title),\n' +
'-      createDescriptionMessage(gitDetails.description),\n' +
'-      // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n' +
'-      // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n' +
'-      // limits include the token count from both the message array sent and the\n' +
'-      // model response. The number of tokens in the messages array combined\n' +
'-      // with the value of the max_tokens parameter must stay under these limits\n' +
"-      // or you'll receive an error.\n" +
'-      // TODO: combine into several requests if diff is too big\n' +
'-      ...splitDiff(gitDetails.diff).slice(0, 1),\n' +
'-      commandToExecuteTheTask(),\n' +
'-    ];\n' +
'-\n' +
"     if (verbose) console.info('Messages:', messages);\n" +
"     if (verbose) console.info('Sending request to OpenAI API...');\n" +
' \n' +
'@@ -150,10 +159,58 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri\n' +
'       temperature: TEMPERATURE,\n' +
'     });\n' +
' \n' +
"-    if (verbose) console.info('completion:', completion);\n" +
'     return completion.data.choices[0]?.message?.content;\n' +
'   } catch (error) {\n' +
"     console.error('Error while calling OpenAI API:', error);\n" +
'     return undefined;\n' +
'   }\n' +
' }\n' +
'+\n' +
'+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {\n' +
'+  if (verbose) logContext(gitDetails);\n' +
'+\n' +
'+  const diffs = splitDiff(gitDetails.diff);\n' +
'+  const baseMessage = [\n' +
'+    reviewSystemMessage,\n' +
'+    createReviewTaskMessage(gitDetails.title),\n' +
'+    createDescriptionMessage(gitDetails.description),\n' +
'+  ];\n' +
'+\n' +
'+  const messages: ChatCompletionRequestMessage[][] = [];\n' +
'+  for (const d of diffs) {\n' +
'+    messages.push([...baseMessage, d, commandToExecuteTheTask()]);\n' +
'+  }\n' +
'+\n' +
'+  const reviews: string[] = [];\n' +
'+  for await (const m of messages) {\n' +
'+    const reviewChunk = await completionRequest(m, verbose);\n' +
'+    if (reviewChunk) {\n' +
'+      reviews.push(reviewChunk);\n' +
'+    }\n' +
'+  }\n' +
'+  if (reviews.length === 0) {\n' +
"+    console.error('No reviews were generated.');\n" +
'+    return undefined;\n' +
'+  }\n' +
'+\n' +
"+  if (verbose) console.info('reviews:', reviews.join('\n'));\n" +
'+  return reviews;\n' +
'+}\n' +
'+\n' +
'+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {\n' +
'+  // The token limit for gpt-35-turbo is 4096 tokens, whereas the token\n' +
'+  // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These\n' +
'+  // limits include the token count from both the message array sent and the\n' +
'+  // model response. The number of tokens in the messages array combined\n' +
'+  // with the value of the max_tokens parameter must stay under these limits\n' +
"+  // or you'll receive an error. Therefore, we need to split the diff into\n" +
'+  // a separet review requests and then combine them into a single review.\n' +
'+  const reviews = await requestReviews(gitDetails, verbose);\n' +
'+  if (!reviews) {\n' +
"+    console.error('No reviews were generated.');\n" +
"+    throw new Error('No reviews were generated.');\n" +
'+  }\n' +
'+\n' +
"+  const summaryTask = createSummaryTask(reviews.join('---\n'));\n" +
'+  return await completionRequest([summarySystemMessage, summaryTask], verbose);\n' +
'+}\n' +
'\n' +
'-----\n' +
'\n' +
'Do not provide feedback yet. I will follow-up additional diff in a new message.\n'
},
{
role: 'user',
content: 'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.'
}
]
Sending request to OpenAI API...
reviews: Positive feedback:

The changeset appears to have addressed the issue of token limits for various GPT models.
The code changes are modularized and organized.
The codebase uses consistent naming conventions and coding style.

Negative feedback:

The wording of the task message could be clearer and more concise.

The commands used to execute the task could be refactored for better readability.

The codebase could use more comments to help a reviewer understand the code more easily.

There is no mention of test coverage or test quality in the task message.
Messages: [
{
role: 'system',
content: 'You are a programming code change reviewer of the open source code. Make a summary of the review provided by other reviewers. Do not introduce yourselves.'
},
{
role: 'user',
content: '\n' +
'  Your task is:\n' +
'  - To make a summary of the reviews that are provided to the same code change.\n' +
'  - Those reviews are on the different git diffs of the same git patch or pull request.\n' +
'\n' +
'  -----\n' +
'  Positive feedback:\n' +
'- The changeset appears to have addressed the issue of token limits for various GPT models.\n' +
'- The code changes are modularized and organized.\n' +
'- The codebase uses consistent naming conventions and coding style.\n' +
'\n' +
'Negative feedback:\n' +
'- The wording of the task message could be clearer and more concise.\n' +
'- The commands used to execute the task could be refactored for better readability.\n' +
'- The codebase could use more comments to help a reviewer understand the code more easily.\n' +
'- There is no mention of test coverage or test quality in the task message.\n' +
'  -----\n' +
'\n' +
'  Make a summary of the reviews as the bullet points.\n' +
'  '
}
]
Sending request to OpenAI API...
Review task completed!

Positive feedback:

Changeset addresses token limits for various GPT models.
Code changes are modularized and organized.
Consistent naming conventions and coding style.

Negative feedback:

Task message could be clearer and more concise.
Commands used to execute the task could be refactored for better readability.
Codebase could use more comments for better understanding.
No mention of test coverage or quality in task message.

Automatic review for commit 13ebba74f91b04b207556df74008764d7676151b:
You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.
{
role: 'user',
content: 'The change has the following title: refactor: Split review task into chunks to avoid token limit.\n' +
'\n' +
'  Your task is:\n' +
'  - Review code, give feedback\n' +
'  - Find, prioritize bugs\n' +
'  - Ensure commit message alignment\n' +
'  - Follow best practices, guidelines:\n' +
'  - Readability, maintainability, docs\n' +
'  - No scope creep\n' +
'  - Consistent naming, style\n' +
'  - Modular organization\n' +
'  - Review performance, optimization:\n' +
'  - Spot bottlenecks\n' +
'  - Propose improvements\n' +
'  - Examine test coverage:\n' +
'  - Verify unit tests\n' +
'  - Identify edge cases\n' +
'  - Assess integration needs\n' +
'  - Assess reusability:\n' +
'  - Leverage existing resources\n' +
'  - Spot reusable components\n' +
'  - Confirm compatibility, security\n' +
'  - Clarify commit messages\n' +
'  - List negative feedback only\n' +
'\n' +
'  Do not provide feedback yet. I will follow-up with a description of the change in a new message.\n' +
'  '
}
A description was given to help you assist in understand why these changes were made:
To accommodate the token limits for various GPT models:

gpt-35-turbo: 4096 tokens
gpt-4: 8192 tokens
gpt-4-32k: 32768 tokens

These limits include tokens from both the message array and model
response. The combined token count of the messages array and max_tokens
parameter must stay within these limits to avoid errors.
To address this, we:

Split the diff into separate review requests
Combine the individual requests into a single review

Do not provide feedback yet. I will follow-up with a diff of the change in a new message.

diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index bdaa15d..b66e6a1 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -38,7 +38,7 @@ jobs:
script: |
const fs = require('fs');
const filePath = 'review.txt';

       const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(3,-2).join('\n');

       const fileContents = fs.readFileSync(filePath, 'utf-8').split('\n').slice(2,-2).join('\n');
       const output = `**Automatic review for commit ${{ github.event.pull_request.head.sha || github.sha }}:**\n${fileContents}`;
       await github.issues.createComment({
         owner: context.repo.owner,

diff --git a/src/index.ts b/src/index.ts
index faff329..95f5af8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -19,6 +19,7 @@ if (gitDetails instanceof Error) {
job(gitDetails)
.then((review: string | undefined) => {
if (!review) {

 console.log('Review task failed!');
 throw new Error('Review task failed');

}

diff --git a/src/review.ts b/src/review.ts
index 7f7d295..3666bdc 100644
--- a/src/review.ts
+++ b/src/review.ts
@@ -25,39 +25,37 @@ const configuration = new Configuration({
const openai = new OpenAIApi(configuration);
-const systemMessage: ChatCompletionRequestMessage = {
+const reviewSystemMessage: ChatCompletionRequestMessage = {
role: 'system',
content:
'You are a programming code change reviewer of the open source code. Provide feedback on the code changes given. Do not introduce yourselves.',
};
-function createTaskMessage(title: string): ChatCompletionRequestMessage {
+function createReviewTaskMessage(title: string): ChatCompletionRequestMessage {
const content = `The change has the following title: ${title}.
Your task is:

Review code changes and provide feedback:

Check for bugs and highlight them.

Verify alignment with commit messages.

Sort issues from major to minor.

Ensure adherence to best practices and project guidelines:

Code readability, maintainability, and documentation.

Consistent naming conventions and coding style.

Modular and organized functions and classes.

Analyze performance and optimization:

Identify potential performance bottlenecks.

Suggest optimizations or efficient algorithms.

Assess test coverage and quality:

Confirm appropriate unit tests are added or updated.

Check for untested edge cases.

Determine if integration tests are needed.

Evaluate code reusability:

Encourage use of existing libraries, frameworks, or code snippets.

Identify opportunities for reusable components or patterns.

Confirm cross-browser and cross-platform compatibility:

Provide security recommendations, if applicable.

Check the commit message for clear descriptions of changes.

Provide feedback as the numbered list.

focus only on negative parts.

Review code, give feedback

Find, prioritize bugs

Ensure commit message alignment

Follow best practices, guidelines:

Readability, maintainability, docs

No scope creep

Consistent naming, style

Modular organization

Review performance, optimization:

Spot bottlenecks

Propose improvements

Examine test coverage:

Verify unit tests

Identify edge cases

Assess integration needs

Assess reusability:

Leverage existing resources

Spot reusable components

Confirm compatibility, security

Clarify commit messages

List negative feedback only

Do not provide feedback yet. I will follow-up with a description of the change in a new message.
`;
@@ -108,7 +106,34 @@ Do not provide feedback yet. I will follow-up additional diff in a new message.

function commandToExecuteTheTask(): ChatCompletionRequestMessage {
const content =

'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters.';

'All code changes have been provided. Please provide me with your code review based on all the changes, context & title provided. Make it succinct and to the point using less than 3000 characters. Use bullet points to summarize your review.';
return {
role: 'user',
content,
};
+}

+const summarySystemMessage: ChatCompletionRequestMessage = {

role: 'system',
content:
'You are a programming code change reviewer of the open source code. Combine reviews provided by other reviewers. Do not introduce yourselves.',
+};

+function createSummaryTask(reviewChunk: string): ChatCompletionRequestMessage {

const content = `
Your task is:

Combine reviews provided by other reviewers

Those reviews are on the different git diffs of the same git patch or pull request.

Do not introduce yourselves.

Do not loose information from the reviews.

${reviewChunk.slice(0, MAX_CONTENT_SIZE)}

Make a summary of the reviews as the bullet points.
`;
return {
role: 'user',
content,
@@ -116,32 +141,17 @@ function commandToExecuteTheTask(): ChatCompletionRequestMessage {
}

export function logContext(gitDetails: GitDetails) {

console.info(systemMessage.content);
console.info(createTaskMessage(gitDetails.title));

console.info(reviewSystemMessage.content);
console.info(createReviewTaskMessage(gitDetails.title));
console.info(createDescriptionMessage(gitDetails.description).content);
console.info(createDiffMessage(gitDetails.diff).content);
}

-export async function job(gitDetails: GitDetails, verbose = false): Promise<string | undefined> {

if (verbose) logContext(gitDetails);

+async function completionRequest(

messages: ChatCompletionRequestMessage[],
verbose: boolean,
+): Promise<string | undefined> {
try {

const messages = [

 systemMessage,

 createTaskMessage(gitDetails.title),

 createDescriptionMessage(gitDetails.description),

 // The token limit for gpt-35-turbo is 4096 tokens, whereas the token

 // limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These

 // limits include the token count from both the message array sent and the

 // model response. The number of tokens in the messages array combined

 // with the value of the max_tokens parameter must stay under these limits

 // or you'll receive an error.

 // TODO: combine into several requests if diff is too big

 ...splitDiff(gitDetails.diff).slice(0, 1),

 commandToExecuteTheTask(),

];

if (verbose) console.info('Messages:', messages);
if (verbose) console.info('Sending request to OpenAI API...');
const completion = await openai.createChatCompletion({
@@ -150,10 +160,58 @@ export async function job(gitDetails: GitDetails, verbose = false): Promise<stri
temperature: TEMPERATURE,
});

if (verbose) console.info('completion:', completion);
return completion.data.choices[0]?.message?.content;
} catch (error) {
console.error('Error while calling OpenAI API:', error);
return undefined;
}
}

+async function requestReviews(gitDetails: GitDetails, verbose: boolean): Promise<string[] | undefined> {

if (verbose) logContext(gitDetails);

const diffs = splitDiff(gitDetails.diff);
const baseMessage = [
reviewSystemMessage,
createReviewTaskMessage(gitDetails.title),
createDescriptionMessage(gitDetails.description),
];

const messages: ChatCompletionRequestMessage[][] = [];
for (const d of diffs) {
messages.push([...baseMessage, d, commandToExecuteTheTask()]);
}

const reviews: string[] = [];
for await (const m of messages) {
const reviewChunk = await completionRequest(m, verbose);
if (reviewChunk) {

 reviews.push(reviewChunk);

}
}
if (reviews.length === 0) {
console.error('No reviews were generated.');
return undefined;
}

if (verbose) console.info('reviews:', reviews.join('\n'));
return reviews;
+}

+export async function job(gitDetails: GitDetails, verbose = true): Promise<string | undefined> {

// The token limit for gpt-35-turbo is 4096 tokens, whereas the token
// limits for gpt-4 and gpt-4-32k are 8192 and 32768 respectively. These
// limits include the token count from both the message array sent and the
// model response. The number of tokens in the messages array combined
// with the value of the max_tokens parameter must stay under these limits
// or you'll receive an error. Therefore, we need to split the diff into
// a separet review requests and then combine them into a single review.
const reviews = await requestReviews(gitDetails, verbose);
if (!reviews) {
console.error('No reviews were generated.');
throw new Error('No reviews were generated.');
}

const summaryTask = createSummaryTask(reviews.join('---\n'));
return await completionRequest([summarySystemMessage, summaryTask], verbose);
+}

Do not provide feedback yet. I will follow-up additional diff in a new message.
Sending request to OpenAI API...
reviews: Positive Feedback:

The code changes are well organized and avoid scope creep.
The commit messages are clear and informative.

Negative Feedback:

The variable name "reviewSystemMessage" in review.ts is a bit misleading and should be renamed as "initialReviewMessage" to avoid confusion.
The "review" variable in job() function in index.ts should be renamed to "summary" to better reflect its meaning.
The "job" function in index.ts has a parameter named "verbose" which is not used. It should either be used or removed.
The "MAX_CONTENT_SIZE" constant in review.ts should be defined as a configuration parameter to allow changing it without modifying the code.
Sending request to OpenAI API...
Review task completed!
Code changes are well organized and avoid scope creep
Commit messages are clear and informative
The variable name "reviewSystemMessage" in review.ts should be renamed to "initialReviewMessage" to avoid confusion
The "review" variable in job() function in index.ts should be renamed to "summary" to better reflect its meaning
The "job" function in index.ts has a parameter named "verbose" which is not used. It should either be used or removed
The "MAX_CONTENT_SIZE" constant in review.ts should be defined as a configuration parameter to allow changing it without modifying the code.

Automatic review for commit d3f0001b1178c04409b3bc91e9863b1506ce1410:
Review task completed!
Summary of reviews:

Positive feedback on code documentation, diff splitting, code structure, and variable naming.
Negative feedback on commit message, undefined constant, function naming, function responsibilities, and code refactoring using Promise.all.

Automatic review for commit 316c0651b90729975ca0fdacd56a34e18bea9485:
Review task completed!
Summary:

The change addresses token limits for GPT models.
The code has been refactored to avoid errors.
The commit messages are clear.
Better documentation is needed for readers to understand the code.
Some parts of the code could be made more modular and reusable.
Naming convention for variables and functions could be improved.
MAX_CONTENT_SIZE constant is missing from the code.

Automatic review for commit 67797cf827111b1e3effb90990b07001af3b43b9:
Review task completed!
Overall, the code changes are well done and address the token limit issue. Here are some specific feedback and suggestions:
Feedback:

The approach of splitting the review task into chunks is a good solution.
The commit message is clear and follows best practices.
The variable and function names are descriptive and consistent.
The code organization is modular and easy to understand.
The test coverage is not mentioned in the commit message.

Bugs:

No bugs were identified.

Optimization:

The splitDiff() function can be further optimized to handle large diffs.

Reusability:

The code can be reused for other OpenAI API services.

Integration:

It is unclear if the code has been integrated with other systems.

Negative feedback:

None found.

Automatic review for commit 53c6698dfb60fbfcde569b546c172791fe38edc4:

The changes aim to avoid token limit in GPT models by splitting the review task into chunks
Main changes include splitting the diff into separate review requests, combining those requests into a single review, and creating separate messages for review task and summary task
Code changes follow best practices and guidelines such as readability, maintainability, documentation, modular organization, and consistent naming
Test coverage is also examined, and negative feedback is requested
The code change is well-structured and should improve the performance and optimization of the code.

Automatic review for commit 80431ebb2946e4fb0def97de710eadcd3b47ea24:

The change addresses token limits on various GPT models.
Refactor splits diff into separate review requests to avoid token limits.
Code is modular and organized.
Commit message could be more descriptive.
createTaskMessage function could be renamed to createReviewTaskMessage to improve clarity.
job function could benefit from better error handling and logging.
Code could use more comments to improve readability and maintainability.
MAX_CONTENT_SIZE constant is not defined in the code provided, so it may cause issues during execution.
requestReviews function could benefit from more descriptive naming.