Initial upload: Git Commit AI - privacy-first CLI for generating commit messages with local LLM
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
109
git_commit_ai/prompts/__init__.py
Normal file
109
git_commit_ai/prompts/__init__.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
"""Prompt management for Git Commit AI."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from git_commit_ai.core.config import Config, get_config
|
||||||
|
|
||||||
|
|
||||||
|
class PromptBuilder:
|
||||||
|
"""Builder for commit message prompts."""
|
||||||
|
|
||||||
|
DEFAULT_PROMPT = """You are a helpful assistant that generates git commit messages.
|
||||||
|
|
||||||
|
Analyze the following git diff and generate a concise, descriptive commit message.
|
||||||
|
The message should:
|
||||||
|
- Be clear and descriptive
|
||||||
|
- Explain what changed and why
|
||||||
|
- Be in present tense
|
||||||
|
- Not exceed 72 characters for the first line if possible
|
||||||
|
|
||||||
|
Git diff:
|
||||||
|
```
|
||||||
|
{diff}
|
||||||
|
```
|
||||||
|
|
||||||
|
{few_shot}
|
||||||
|
|
||||||
|
Generate 3 different commit message suggestions, one per line.
|
||||||
|
Format: Just the commit messages, one per line, nothing else.
|
||||||
|
|
||||||
|
Suggestions:
|
||||||
|
"""
|
||||||
|
|
||||||
|
CONVENTIONAL_PROMPT = """You are a helpful assistant that generates conventional git commit messages.
|
||||||
|
|
||||||
|
Generate a commit message in the conventional commit format:
|
||||||
|
- type(scope): description
|
||||||
|
- Examples: feat(auth): add login, fix: resolve memory leak
|
||||||
|
|
||||||
|
Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
||||||
|
|
||||||
|
Analyze the following git diff and generate commit messages.
|
||||||
|
Git diff:
|
||||||
|
```
|
||||||
|
{diff}
|
||||||
|
```
|
||||||
|
|
||||||
|
{few_shot}
|
||||||
|
|
||||||
|
Generate 3 different commit message suggestions, one per line.
|
||||||
|
Format: Just the commit messages, one per line, nothing else.
|
||||||
|
|
||||||
|
Suggestions:
|
||||||
|
"""
|
||||||
|
|
||||||
|
SYSTEM_DEFAULT = "You are a helpful assistant that generates clear and concise git commit messages."
|
||||||
|
|
||||||
|
SYSTEM_CONVENTIONAL = "You are a helpful assistant that generates conventional git commit messages. Always use the format: type(scope): description. Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
|
||||||
|
|
||||||
|
def __init__(self, config: Optional[Config] = None):
|
||||||
|
self.config = config or get_config()
|
||||||
|
self._prompt_dir = Path(self.config.prompt_directory)
|
||||||
|
|
||||||
|
def build_prompt(self, diff: str, context: Optional[str] = None, conventional: bool = False) -> str:
|
||||||
|
few_shot = self._build_few_shot(context)
|
||||||
|
|
||||||
|
if conventional:
|
||||||
|
template = self._get_conventional_template()
|
||||||
|
else:
|
||||||
|
template = self._get_default_template()
|
||||||
|
|
||||||
|
prompt = template.format(diff=diff[:10000] if len(diff) > 10000 else diff, few_shot=few_shot)
|
||||||
|
return prompt
|
||||||
|
|
||||||
|
def _get_default_template(self) -> str:
|
||||||
|
custom_path = self._prompt_dir / "default.txt"
|
||||||
|
if custom_path.exists():
|
||||||
|
return custom_path.read_text()
|
||||||
|
return self.DEFAULT_PROMPT
|
||||||
|
|
||||||
|
def _get_conventional_template(self) -> str:
|
||||||
|
custom_path = self._prompt_dir / "conventional.txt"
|
||||||
|
if custom_path.exists():
|
||||||
|
return custom_path.read_text()
|
||||||
|
return self.CONVENTIONAL_PROMPT
|
||||||
|
|
||||||
|
def _build_few_shot(self, context: Optional[str]) -> str:
|
||||||
|
if not context:
|
||||||
|
return ""
|
||||||
|
return f"\n\nRecent commit history for context:\n{context}"
|
||||||
|
|
||||||
|
def get_system_prompt(self, conventional: bool = False) -> str:
|
||||||
|
if conventional:
|
||||||
|
custom_path = self._prompt_dir / "system_conventional.txt"
|
||||||
|
if custom_path.exists():
|
||||||
|
return custom_path.read_text()
|
||||||
|
return self.SYSTEM_CONVENTIONAL
|
||||||
|
|
||||||
|
custom_path = self._prompt_dir / "system_default.txt"
|
||||||
|
if custom_path.exists():
|
||||||
|
return custom_path.read_text()
|
||||||
|
return self.SYSTEM_DEFAULT
|
||||||
|
|
||||||
|
def get_supported_languages(self) -> list[str]:
|
||||||
|
return ["Python", "JavaScript", "TypeScript", "Java", "Go", "Rust", "Ruby", "PHP", "C", "C++", "C#", "Swift", "Kotlin", "Scala", "HTML", "CSS", "SQL", "Shell"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_prompt_builder(config: Optional[Config] = None) -> PromptBuilder:
|
||||||
|
return PromptBuilder(config)
|
||||||
Reference in New Issue
Block a user