* 🚀 feat(generateCommitMessageFromGitDiff.ts): add mergeStrings utility function

* 🐛 fix(generateCommitMessageFromGitDiff.ts): remove unnecessary separator variable

* 🐛 fix: split file diffs by files
*  feat: add support for generating commit messages by file diffs

*  feat(generateCommitMessageFromGitDiff.ts): add mergeStrings utility function to merge string arrays
* 🐛 fix(generateCommitMessageFromGitDiff.ts): reduce MAX_REQ_TOKENS to 1000
*  feat(generateCommitMessageFromGitDiff.ts): add support for generating commit messages for large diffs by splitting them into smaller chunks and generating commit messages for each chunk using OpenAI's GPT-3 model.

* ♻️ refactor: extract getCommitMsgsPromisesFromFileDiffs function from generateCommitMessage function
* ♻️ refactor: extract getMessagesPromisesByLines function from getCommitMsgsPromisesFromFileDiffs function
*  feat: add support for merging file diffs into one commit message if it exceeds MAX_REQ_TOKENS limit

*  feat(mergeStrings.ts): add mergeStrings function to merge strings in an array based on maxStringLength
This commit is contained in:
di-sukharev
2023-03-07 16:19:00 +08:00
parent 9e2a3d8988
commit bf29c260ca
4 changed files with 175 additions and 26 deletions

View File

@@ -43,6 +43,8 @@ class OpenAi {
public generateCommitMessage = async (
messages: Array<ChatCompletionRequestMessage>
): Promise<string | undefined> => {
console.log({ messages });
try {
const { data } = await this.openAI.createChatCompletion({
model: 'gpt-3.5-turbo',

View File

@@ -4,6 +4,7 @@ import {
} from 'openai';
import { api } from './api';
import { getConfig } from './commands/config';
import { mergeStrings } from './utils/mergeStrings';
const config = getConfig();
@@ -81,43 +82,28 @@ const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
(msg) => msg.content
).join('').length;
const MAX_REQ_TOKENS = 3900 - INIT_MESSAGES_PROMPT_LENGTH;
const MAX_REQ_TOKENS = 1000 - INIT_MESSAGES_PROMPT_LENGTH;
export const generateCommitMessageWithChatCompletion = async (
diff: string
): Promise<string | GenerateCommitMessageError> => {
try {
if (diff.length >= MAX_REQ_TOKENS) {
const separator = 'diff --git ';
const diffByFiles = diff.split(separator).slice(1);
const commitMessagePromises = diffByFiles
.map((fileDiff) => {
// TODO: split by files
if (fileDiff.length >= MAX_REQ_TOKENS) return null;
const messages = generateCommitMessageChatCompletionPrompt(
separator + fileDiff
);
return api.generateCommitMessage(messages);
})
.filter(Boolean);
const commitMessagePromises = getCommitMsgsPromisesFromFileDiffs(diff);
const commitMessages = await Promise.all(commitMessagePromises);
return commitMessages.join('\n\n');
} else {
const messages = generateCommitMessageChatCompletionPrompt(diff);
const commitMessage = await api.generateCommitMessage(messages);
if (!commitMessage)
return { error: GenerateCommitMessageErrorEnum.emptyMessage };
return commitMessage;
}
const messages = generateCommitMessageChatCompletionPrompt(diff);
const commitMessage = await api.generateCommitMessage(messages);
if (!commitMessage)
return { error: GenerateCommitMessageErrorEnum.emptyMessage };
return commitMessage;
} catch (error) {
return { error: GenerateCommitMessageErrorEnum.internalError };
}
@@ -139,3 +125,30 @@ function getMessagesPromisesByLines(fileDiff: string, separator: string) {
return commitMsgsFromFileLineDiffs;
}
function getCommitMsgsPromisesFromFileDiffs(diff: string) {
const separator = 'diff --git ';
const diffByFiles = diff.split(separator).slice(1);
const mergedDiffs = mergeStrings(diffByFiles, MAX_REQ_TOKENS);
const commitMessagePromises = [];
for (const fileDiff of mergedDiffs) {
if (fileDiff.length >= MAX_REQ_TOKENS) {
// split fileDiff into lineDiff
const messagesPromises = getMessagesPromisesByLines(fileDiff, separator);
commitMessagePromises.push(...messagesPromises);
} else {
// generate commits for files
const messages = generateCommitMessageChatCompletionPrompt(
separator + fileDiff
);
commitMessagePromises.push(api.generateCommitMessage(messages));
}
}
return commitMessagePromises;
}

14
src/utils/mergeStrings.ts Normal file
View File

@@ -0,0 +1,14 @@
export function mergeStrings(arr: string[], maxStringLength: number): string[] {
const mergedArr: string[] = [];
let currentItem: string = arr[0];
for (const item of arr.slice(1)) {
if (currentItem.length + item.length <= maxStringLength) {
currentItem += item;
} else {
mergedArr.push(currentItem);
currentItem = item;
}
}
mergedArr.push(currentItem);
return mergedArr;
}