Skip to content

Commit bcbef11

Browse files
committed
feat(commitlint): improve consistency handling and update prompt structure for commit message generation
Enhancements are made to the consistency handling in the commitlint integration, including the introduction of a new structure for consistency prompts. The getConsistencyContent function is updated to accommodate the new format, allowing for better management of commit messages and their associated configuration settings. Additionally, the prompts for generating commit messages are refined to ensure clarity and adherence to the specified requirements.
1 parent beaad14 commit bcbef11

File tree

5 files changed

+77
-35
lines changed

5 files changed

+77
-35
lines changed

src/engine/deepseek.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import axios from 'axios';
22
import { OpenAI } from 'openai';
33
import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitDiff';
44
import { tokenCount } from '../utils/tokenCount';
5-
import { OpenAiEngine, OpenAiConfig } from './openAI';
5+
import { OpenAiEngine, OpenAiConfig } from './openAi';
66

77
export interface DeepseekConfig extends OpenAiConfig {}
88

src/modules/commitlint/config.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,26 @@ export const configureCommitlintIntegration = async (force = false) => {
6565
// );
6666

6767
const engine = getEngine();
68-
let consistency =
69-
(await engine.generateCommitMessage(consistencyPrompts)) || '{}';
68+
let consistency = (await engine.generateCommitMessage(consistencyPrompts)) || '';
7069

7170
// Cleanup the consistency answer. Sometimes 'gpt-3.5-turbo' sends rule's back.
7271
prompts.forEach((prompt) => (consistency = consistency.replace(prompt, '')));
7372

74-
// sometimes consistency is preceded by explanatory text like "Here is your JSON:"
75-
consistency = utils.getJSONBlock(consistency);
76-
77-
// ... remaining might be extra set of "\n"
78-
consistency = utils.removeDoubleNewlines(consistency);
73+
// Cleanup any potential extra text or formatting
74+
consistency = consistency.trim();
7975

8076
const commitlintLLMConfig: CommitlintLLMConfig = {
8177
hash,
8278
prompts,
8379
consistency: {
8480
[translation.localLanguage]: {
85-
...JSON.parse(consistency as string)
81+
commitMessage: consistency,
82+
// Store config settings that were used to generate this message
83+
config: {
84+
OCO_OMIT_SCOPE: config.OCO_OMIT_SCOPE,
85+
OCO_DESCRIPTION: config.OCO_DESCRIPTION,
86+
OCO_EMOJI: config.OCO_EMOJI
87+
}
8688
}
8789
}
8890
};

src/modules/commitlint/prompts.ts

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111

1212
import { getConfig } from '../../commands/config';
1313
import { i18n, I18nLocals } from '../../i18n';
14-
import { IDENTITY, INIT_DIFF_PROMPT } from '../../prompts';
14+
import { IDENTITY, INIT_DIFF_PROMPT, getConsistencyContent } from '../../prompts';
1515

1616
const config = getConfig();
1717
const translation = i18n[(config.OCO_LANGUAGE as I18nLocals) || 'en'];
@@ -213,10 +213,27 @@ const STRUCTURE_OF_COMMIT = config.OCO_OMIT_SCOPE
213213
// Prompt to generate LLM-readable rules based on @commitlint rules.
214214
const GEN_COMMITLINT_CONSISTENCY_PROMPT = (
215215
prompts: string[]
216-
): OpenAI.Chat.Completions.ChatCompletionMessageParam[] => [
216+
): OpenAI.Chat.Completions.ChatCompletionMessageParam[] => {
217+
// Get the default content as reference
218+
const defaultContent = getConsistencyContent(translation);
219+
220+
// Build dynamic requirements based on config
221+
const dynamicRequirements = [
222+
config.OCO_OMIT_SCOPE
223+
? '- Do not include scope in the commit message'
224+
: '- Include appropriate scope in the commit message',
225+
config.OCO_DESCRIPTION
226+
? '- Include a description explaining the changes'
227+
: '- Do not include a description',
228+
config.OCO_EMOJI
229+
? '- Use appropriate emoji at the start of the message'
230+
: '- Do not use emoji'
231+
].join('\n');
232+
233+
return [
217234
{
218235
role: 'system',
219-
content: `${IDENTITY} Your mission is to create clean and comprehensive commit messages for two different changes in a single codebase and output them in the provided JSON format: one for a bug fix and another for a new feature.
236+
content: `${IDENTITY} Your mission is to create a clean and comprehensive commit message that follows both the commitlint rules and maintains the style of the reference message.
220237
221238
Here are the specific requirements and conventions that should be strictly followed:
222239
@@ -226,29 +243,25 @@ Commit Message Conventions:
226243
- Format: ${config.OCO_OMIT_SCOPE ? '`<type>: <subject>`' : '`<type>(<scope>): <subject>`'}
227244
- ${prompts.join('\n- ')}
228245
229-
JSON Output Format:
230-
- The JSON output should contain the commit messages for a bug fix and a new feature in the following format:
231-
\`\`\`json
232-
{
233-
"localLanguage": "${translation.localLanguage}",
234-
"commitFix": "<Header of commit for bug fix with scope>",
235-
"commitFeat": "<Header of commit for feature with scope>",
236-
"commitFixOmitScope": "<Header of commit for bug fix without scope>",
237-
"commitFeatOmitScope": "<Header of commit for feature without scope>",
238-
"commitDescription": "<Description of commit for both the bug fix and the feature>"
239-
}
240-
\`\`\`
241-
- The "commitDescription" should not include the commit message’s header, only the description.
242-
- Description should not be more than 74 characters.
246+
${dynamicRequirements}
247+
248+
Reference Message Style:
249+
${defaultContent}
243250
244-
Additional Details:
245-
- Changing the variable 'port' to uppercase 'PORT' is considered a bug fix.
246-
- Allowing the server to listen on a port specified through the environment variable is considered a new feature.
251+
Output Format:
252+
- Generate a single commit message that:
253+
1. Follows all commitlint rules above
254+
2. Maintains the style and features of the reference message
255+
3. Follows the specific requirements above
256+
- The message should be a complete, valid commit message that would pass commitlint validation
257+
- Do not include any JSON formatting or additional text
258+
- The message should be ready to use as a git commit message
247259
248260
Example Git Diff is to follow:`
249261
},
250262
INIT_DIFF_PROMPT
251263
];
264+
};
252265

253266
/**
254267
* Prompt to have LLM generate a message using @commitlint rules.
@@ -283,9 +296,7 @@ ${config.OCO_OMIT_SCOPE
283296
}
284297
You will strictly follow the following conventions to generate the content of the commit message:
285298
- ${prompts.join('\n- ')}
286-
287-
The conventions refers to the following structure of commit message:
288-
${STRUCTURE_OF_COMMIT}`
299+
`
289300
});
290301

291302
export const commitlintPrompts = {

src/modules/commitlint/types.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
import { i18n } from '../../i18n';
22

3-
export type ConsistencyPrompt = (typeof i18n)[keyof typeof i18n];
3+
export type DefaultConsistencyPrompt = {
4+
commitFix: string;
5+
commitFeat: string;
6+
commitFixOmitScope: string;
7+
commitFeatOmitScope: string;
8+
commitDescription: string;
9+
};
10+
11+
export type CommitlintConsistencyPrompt = {
12+
commitMessage: string;
13+
config: {
14+
OCO_OMIT_SCOPE: boolean;
15+
OCO_DESCRIPTION: boolean;
16+
OCO_EMOJI: boolean;
17+
};
18+
};
19+
20+
export type ConsistencyPrompt = DefaultConsistencyPrompt | CommitlintConsistencyPrompt;
421

522
export type CommitlintLLMConfig = {
623
hash: string;

src/prompts.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,20 @@ const generateCommitString = (
198198
: message;
199199
};
200200

201-
const getConsistencyContent = (translation: ConsistencyPrompt) => {
201+
export const getConsistencyContent = (translation: ConsistencyPrompt) => {
202+
// Check if we're using the new commitlint format
203+
if ('commitMessage' in translation) {
204+
const message = translation.commitMessage;
205+
// Only add emoji if it was enabled when the message was generated
206+
if (translation.config.OCO_EMOJI && !message.match(/^[^\s]*\s/)) {
207+
const type = message.split(':')[0].toLowerCase();
208+
const emoji = COMMIT_TYPES[type as keyof typeof COMMIT_TYPES] || '✨';
209+
return `${emoji} ${message}`;
210+
}
211+
return message;
212+
}
213+
214+
// Handle the old default format (JSON-based)
202215
const fixMessage = config.OCO_OMIT_SCOPE && translation.commitFixOmitScope
203216
? translation.commitFixOmitScope
204217
: translation.commitFix;
@@ -239,7 +252,6 @@ export const getMainCommitPrompt = async (
239252

240253
// Replace example prompt with a prompt that's generated by OpenAI for the commitlint config.
241254
const commitLintConfig = await utils.getCommitlintLLMConfig();
242-
243255
return [
244256
commitlintPrompts.INIT_MAIN_PROMPT(
245257
translation.localLanguage,

0 commit comments

Comments
 (0)