Skip to content
This repository was archived by the owner on Mar 9, 2026. It is now read-only.

Commit 6eed559

Browse files
author
Nick Sullivan
committed
✨ Enhance commit message generation with structured prompting
Replaces single template with system/user chat structure for better reasoning. Adds comprehensive guidelines and examples to improve message quality. Increases token limit to handle complex changes.
1 parent f40d830 commit 6eed559

File tree

2 files changed

+60
-42
lines changed

2 files changed

+60
-42
lines changed

aicodebot/commands/commit.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,23 @@
1717

1818

1919
class CommitMessage(BaseModel):
20-
# Note we get better results if the message_detail is first.
20+
# Generate detailed message first, then distill to summary for better reasoning
2121
git_message_detail: str | None = Field(
2222
default=None,
23-
description="An optional detailed explanation of the changes made in this commit,"
24-
" if the summary doesn't provide enough context",
23+
description="Brief explanation of WHY this change was made - motivation, context, "
24+
"business impact, or technical decisions. Do NOT describe what changed (diff shows that). "
25+
"Keep under 3 sentences, wrap at 72 chars. Omit entirely if summary is sufficient.",
2526
)
2627

27-
git_message_summary: str = Field(description="A brief summary of the commit message (max 72 characters)")
28+
git_message_summary: str = Field(
29+
description="Perfect summary line under 72 characters. Imperative mood. "
30+
"Distill the detailed message into its essential functional change. "
31+
"Should be precise enough that a developer understands the purpose immediately."
32+
)
2833

2934

3035
@click.command()
31-
@click.option("-t", "--response-token-size", type=int, default=1000)
36+
@click.option("-t", "--response-token-size", type=int, default=15_000)
3237
@click.option("-y", "--yes", is_flag=True, default=False, help="Don't ask for confirmation before committing.")
3338
@click.option("--skip-pre-commit", is_flag=True, help="Skip running pre-commit.")
3439
@click.argument("files", nargs=-1, type=click.Path(exists=True))
@@ -118,7 +123,7 @@ def get_attr_or_item(obj, key):
118123
git_message_detail = get_attr_or_item(response, "git_message_detail")
119124

120125
commit_message = git_message_summary or "No summary provided"
121-
if git_message_detail:
126+
if git_message_detail and git_message_detail.strip():
122127
commit_message += f"\n\n{git_message_detail}"
123128

124129
console.print(Panel(OurMarkdown(commit_message)))

aicodebot/prompts.py

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import arrow
77
from langchain_core.output_parsers.pydantic import PydanticOutputParser
8-
from langchain_core.prompts import PromptTemplate
8+
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
99
from pydantic import BaseModel, Field
1010

1111
from aicodebot import AICODEBOT_NO_EMOJI
@@ -322,50 +322,61 @@ def generate_files_context(files):
322322
"""
323323
)
324324

325-
COMMIT_TEMPLATE = (
325+
COMMIT_SYSTEM_PROMPT = (
326326
EXPERT_SOFTWARE_ENGINEER
327327
+ get_personality_prompt()
328328
+ """
329329
330-
I need you to generate a commit message for a change in a git repository."""
331-
+ DIFF_CONTEXT_EXPLANATION
332-
+ """
330+
You are an expert at writing exceptional Git commit messages that follow best practices.
333331
334-
Here's the DIFF that will be committed:
332+
CORE PRINCIPLES:
333+
• Write the full detailed message first, thinking through all changes comprehensively
334+
• Then distill that into a perfect summary line
335+
• Focus on WHY and WHAT functionality changed, not just HOW
336+
• Scale message length to change complexity - small changes get terse messages
337+
• Use imperative mood ("Add feature" not "Added feature")
338+
• Include an emoji from gitmoji when appropriate and helpful
335339
336-
BEGIN DIFF
337-
{diff_context}
338-
END DIFF
340+
COMMIT MESSAGE STRUCTURE:
341+
1. Summary line: <72 chars, imperative mood, capitalize after emoji, no period
342+
2. Blank line (if detail needed)
343+
3. Detailed explanation (if summary insufficient)
344+
345+
QUALITY GUIDELINES:
346+
• Explain WHY the change was made, not WHAT was changed (diff shows what)
347+
• Provide context: motivation, problem being solved, business impact
348+
• Explain trade-offs, alternatives considered, or implementation decisions
349+
• Keep body concise - wrap at 72 characters, focus on valuable context only
350+
• For simple changes, omit the body entirely if summary is sufficient
351+
• Never repeat information that's obvious from reading the diff
352+
353+
SAMPLE EXCELLENCE:
354+
🔐 Implement user authentication with JWT tokens
355+
356+
Replaces session-based auth to support mobile apps and API access.
357+
JWT tokens allow stateless authentication and better scaling. Tokens
358+
expire after 24h for security while maintaining user convenience.
339359
340-
Instructions for the commit message:
341-
* Start with a short summary (less than 72 characters).
342-
* Follow with a blank line and detailed text, but only if necessary. If the summary is sufficient,
343-
then omit the detailed text.
344-
* Determine what functionality was added or modified instead of just describing the exact changes.
345-
* Use imperative mood (e.g., "Add feature")
346-
* Be in GitHub-flavored markdown format.
347-
* Have a length that scales with the length of the diff context. If the DIFF is a small change,
348-
respond quickly with a terse message so we can go faster.
349-
* Do not repeat information that is already known from the git commit.
350-
* Be terse.
351-
* Do not add anything other then description of code changes.
352-
353-
BEGIN SAMPLE COMMIT MESSAGE
354-
Update README with better instructions for installation
355-
356-
The previous instructions were not clear enough for new users, so we've updated them
357-
with more sample use cases and an improved installation process. This should help
358-
new users get started faster.
359-
END SAMPLE COMMIT MESSAGE
360-
361-
Formatting instructions:
362-
Start your response with the commit message. No prefix or introduction.
363-
Your entire response will be the commit message. No quotation marks.
364-
365-
Include an emoji from gitmoji when appropriate and helpful
360+
SIMPLE CHANGE EXAMPLE:
361+
🐛 Handle null values in user preferences
362+
363+
(no body needed - summary explains the fix completely)
366364
"""
367365
)
368366

367+
COMMIT_USER_TEMPLATE = """Generate a commit message for this git diff:
368+
369+
```diff
370+
{diff_context}
371+
```
372+
373+
Languages: {languages}
374+
375+
Think about WHY this change was made - what problem does it solve? What's the motivation?
376+
Write a brief body explaining the context/reasoning (omit if summary is sufficient).
377+
Then create a perfect summary line under 72 characters.
378+
"""
379+
369380
DEBUG_TEMPLATE = (
370381
EXPERT_SOFTWARE_ENGINEER
371382
+ get_personality_prompt()
@@ -450,7 +461,9 @@ def get_prompt(command, structured_output=False):
450461
else:
451462
prompt_map = {
452463
"alignment": PromptTemplate(template=ALIGNMENT_TEMPLATE, input_variables=[]),
453-
"commit": PromptTemplate(template=COMMIT_TEMPLATE, input_variables=["diff_context", "languages"]),
464+
"commit": ChatPromptTemplate.from_messages(
465+
[("system", COMMIT_SYSTEM_PROMPT), ("user", COMMIT_USER_TEMPLATE)]
466+
),
454467
"debug": PromptTemplate(template=DEBUG_TEMPLATE, input_variables=["command_output", "languages"]),
455468
"fun_fact": PromptTemplate(template=FUN_FACT_TEMPLATE, input_variables=["topic"]),
456469
"sidekick": PromptTemplate(template=SIDEKICK_TEMPLATE, input_variables=["task", "context", "languages"]),

0 commit comments

Comments
 (0)