AI Powered Commit Message Normalization Tool
Reason this release was yanked:
Configuration error in extras
Project description
CMAI - AI-Powered Commit Message Normalizer
CMAI is an intelligent command-line tool that leverages AI to transform informal or colloquial commit messages into standardized, professional Git commit messages. It analyzes your staged changes and uses advanced language models to generate clear, concise, and conventional commit messages.
๐ Features
- AI-Powered Normalization: Converts informal commit descriptions into professional, standardized commit messages
- Git Integration: Automatically analyzes staged changes to provide context-aware suggestions
- Multiple AI Provider Support: Supports various AI providers including OpenAI-compatible APIs, Bailian (Qwen), DeepSeek, SiliconFlow, and local Ollama models
- Extensible Architecture: Easy to add new AI providers through the provider factory system
- Configurable: Customizable prompt templates and model settings
- Token Usage Tracking: Monitor AI token consumption for cost management
- Comprehensive Logging: Detailed logging for debugging and monitoring with stream output support
๐ Quick Start
Installation
Install CMAI using pip, or uv as recommended:
uv tool install cmai # Just the core package, without any provider dependencies, you need to install provider-specific extras separately
uv tool install cmai[openai] # For OpenAI-compatible APIs
uv tool install cmai[ollama] # For Ollama local models
uv tool install cmai[all_providers] # For all supported providers
Or install from source:
git clone https://github.com/yumuzhihan/cmai.git
cd cmai
pip install -e .
Quick Setup
- Configure your AI provider (this step is required):
Create ~/.config/cmai/settings.env:
# Example: Using OpenAI
PROVIDER=openai
API_KEY=your_openai_api_key
MODEL=gpt-4o-mini
# Or using Ollama locally
# PROVIDER=ollama
# OLLAMA_HOST=http://localhost:11434
# MODEL=qwen2.5:7b
- Set your API key (if using remote providers):
# For OpenAI
export CMAI_API_KEY=your_api_key
# For Bailian
export CMAI_API_KEY=your_api_key
# For DeepSeek
export CMAI_API_KEY=your_api_key
# For SiliconFlow
export CMAI_API_KEY=your_api_key
# For Ollama, no API key is needed
# For Zai (ๆบ่ฐฑAI)
export CMAI_API_KEY=your_api_key
- Test the installation:
# Stage some changes
git add .
# Generate a commit message
cmai "fixed a bug"
Basic Usage
- Stage your changes in Git:
git add .
- Use CMAI to generate a normalized commit message:
cmai "fix some bugs in user authentication"
- The tool will output a standardized commit message like:
Commit message: Fix authentication bugs in user login module
Tokens used: 45
Elapsed time: 38.94 seconds
Action ([c]ommit / [e]dit / [a]bort) (c, e, a) [c]:
You can then choose to commit, edit, or abort the operation.
Note: If you use Zai (ๆบ่ฐฑAI) as your provider, the token usage will not be provided due to API limitations. So the output tokens usage will be displayed as 0.
โ ๏ธ Important Setup Reminder: Before using CMAI, you must configure at least two settings:
PROVIDER: The AI provider you want to use (e.g.,openai,bailian,ollama)MODEL: The specific model name (this is required for all providers)
Without these configurations, CMAI will fail to run. And most providers require an API key. See the Configuration section for details.
๐ง Configuration
CMAI uses a configuration file located at ~/.config/cmai/settings.env. The configuration file will be automatically created on first run.
Environment Variables
Create or edit ~/.config/cmai/settings.env:
# AI Provider Configuration
PROVIDER=openai
# If API_BASE is not specified, the default base URL of `openai` sdk will be used
API_BASE=https://api.openai.com/v1
API_KEY=your_api_key_here
MODEL=gpt-4o-mini
# For Bailian (Qwen) API
# PROVIDER=bailian
# API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1
# API_KEY=your_dashscope_api_key
# MODEL=qwen-turbo-latest
# For DeepSeek API(Not tested yet)
# PROVIDER=deepseek
# API_BASE=https://api.deepseek.com/v1
# API_KEY=your_deepseek_api_key
# MODEL=deepseek-chat
# For SiliconFlow API
# PROVIDER=siliconflow
# API_BASE=https://api.siliconflow.cn/v1
# API_KEY=your_siliconflow_api_key
# MODEL=Qwen/Qwen2.5-7B-Instruct
# For Ollama (local)
# PROVIDER=ollama
# OLLAMA_HOST=http://localhost:11434
# MODEL=qwen2.5:7b
# Logging Configuration
LOG_LEVEL=INFO
LOG_FILE_PATH=/path/to/logfile.log
# Prompt Template (optional customization)
PROMPT_TEMPLATE=Please generate a standardized commit message based on the user description: {user_input}. The changes include: {diff_content}. Respond only with the normalized commit message in English.
# Token Usage Limit (optional)
DIFF_LENGTH_LIMIT=10000 # Maximum length of diff content to consider, if exceeded, it will only provide a list of the modified files.
Supported AI Providers
CMAI supports multiple AI providers through its extensible architecture:
1. OpenAI-Compatible APIs
- OpenAI: Official OpenAI API
- Bailian (Qwen): Alibaba Cloud's Qwen models
- DeepSeek: DeepSeek's AI models
- SiliconFlow: SiliconFlow's AI services
- ChatGPT: OpenAI ChatGPT models
- Zai (ๆบ่ฐฑAI): Zai's large language models, such as GLM series
2. Local Models
- Ollama: Run models locally using Ollama
Important: Model Configuration
โ ๏ธ Important: You must specify a MODEL in your configuration. CMAI requires an explicit model name to function properly. Examples:
- OpenAI:
gpt-4o-mini,gpt-4o,gpt-3.5-turbo - Bailian:
qwen-turbo-latest,qwen-plus-latest,qwen-max-latest - DeepSeek:
deepseek-chat,deepseek-coder - SiliconFlow:
Qwen/Qwen2.5-7B-Instruct,deepseek-ai/DeepSeek-V2.5 - Ollama:
qwen2.5:7b,llama3.1:8b,codellama:7b - Zai:
glm-4.5-flash,glm-4-0520-bolt
API Key Setup
Different providers require different API keys, and there are two ways to set them up:
- Environment Variable: Set the
CMAI_API_KEYenvironment variable in your shell, and usecmaicommand in the same shell session. The toll will try to extract the API key from the environment variable.
export CMAI_API_KEY=your_api_key_here
- Configuration File: Set the
API_KEYin the~/.config/cmai/settings.envfile. You can also specify the config file path using the--config(or-c) option.
API_KEY=your_api_key_here
๐ Usage Examples
Usage Examples
# Simple commit message normalization (uses configuration file settings)
cmai "updated readme file"
# Using a custom configuration file
cmai "fixed authentication bug" --config /path/to/custom/config.env
# Specifying a different repository
cmai "refactored user service" --repo /path/to/repo
Using Custom Configuration
# Use a specific configuration file
cmai "refactored auth system" --config /path/to/custom/config.env
Specifying Repository Path
# Analyze changes in a specific repository
cmai "fixed login bug" --repo /path/to/your/repo
Full Command Options
cmai [OPTIONS] MESSAGE
Arguments:
MESSAGE The informal commit message to be normalized [required]
Options:
-c, --config TEXT Path to configuration file
-r, --repo TEXT Git repository path
-l, --language TEXT Language for the resulting commit message. It will be passed to the llm by prompt,
e.g., "English", "Chinese", etc.
--help Show this message and exit
Note: Provider and model selection is configured through the configuration file or environment variables, not command-line arguments.
Configuration Examples for Different Providers
To use different AI providers, configure your ~/.config/cmai/settings.env file:
OpenAI
PROVIDER=openai
API_BASE=https://api.openai.com/v1
API_KEY=your_openai_api_key
MODEL=gpt-4o-mini
Bailian (Qwen)
PROVIDER=bailian
API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1
API_KEY=your_dashscope_api_key
MODEL=qwen-turbo-latest
DeepSeek
PROVIDER=deepseek
API_BASE=https://api.deepseek.com/v1
API_KEY=your_deepseek_api_key
MODEL=deepseek-chat
SiliconFlow
PROVIDER=siliconflow
API_BASE=https://api.siliconflow.cn/v1
API_KEY=your_siliconflow_api_key
MODEL=Qwen/Qwen2.5-7B-Instruct
Ollama (Local)
PROVIDER=ollama
OLLAMA_HOST=http://localhost:11434
MODEL=qwen2.5:7b
Zai (ๆบ่ฐฑAI)
PROVIDER=zai
API_BASE=https://open.bigmodel.cn/api/paas/v4/
API_KEY=your_zhipu_api_key
MODEL=glm-4.5-flash
After configuring your preferred provider, simply use:
cmai "your commit message"
๐๏ธ Architecture
CMAI follows a modular architecture with the following components:
Core Components
cmai.main: Entry point and CLI interface using Clickcmai.core.normalizer: Core logic for commit message normalizationcmai.core.get_logger: Logging factory and configuration with stream supportcmai.config.settings: Configuration management using Pydantic
Provider System
cmai.providers.base: Abstract base class for AI providerscmai.providers.openai_provider: OpenAI-compatible API implementationcmai.providers.ollama_provider: Ollama local model implementationcmai.providers.provider_factory: Factory for creating and managing providerscmai.providers.zai_provider: Zai (ๆบ่ฐฑAI) provider implementationcmai.providers.bailian_provider: Legacy Bailian provider (deprecated)
Utilities
cmai.utils.git_staged_analyzer: Git repository analysis and diff extraction
Data Models
class AIResponse(BaseModel):
content: str # The normalized commit message
model: str # AI model used
provider: str # AI provider name
tokens_used: Optional[int] # Token consumption
Provider Factory System
CMAI uses a factory pattern for managing AI providers:
from cmai.providers.provider_factory import create_provider
# Create provider with default settings
provider = create_provider()
# Create specific provider with model
provider = create_provider("openai", model="gpt-4o-mini")
# Create Ollama provider
provider = create_provider("ollama", model="qwen2.5:7b")
๐ Extending CMAI
Adding New AI Providers
To add support for a new AI provider, create a class that inherits from BaseAIClient and register it with the provider factory:
from cmai.providers.base import BaseAIClient, AIResponse
from cmai.providers.provider_factory import register_custom_provider
class CustomProvider(BaseAIClient):
async def normalize_commit(self, prompt: str, **kwargs) -> AIResponse:
# Implement your provider logic here
# Must return AIResponse with content, model, provider, and tokens_used
pass
def validate_config(self) -> bool:
# Implement configuration validation
return True
# Register the provider
register_custom_provider("custom", CustomProvider)
Using the Provider Factory
The provider factory automatically manages different AI providers:
from cmai.providers.provider_factory import (
create_provider,
list_available_providers,
register_custom_provider
)
# List all available providers
providers = list_available_providers()
print(providers)
# Output: {'openai': 'OpenaiProvider', 'ollama': 'OllamaProvider', ...}
# Create provider instances
openai_provider = create_provider("openai", model="gpt-4o-mini")
ollama_provider = create_provider("ollama", model="qwen2.5:7b")
Custom Prompt Templates
You can customize the prompt template by modifying the PROMPT_TEMPLATE setting:
PROMPT_TEMPLATE=Generate a standardized commit message based on: {user_input}. Changes: {diff_content}. Use conventional commit format.
Available placeholders:
{user_input}: The user's informal commit message{diff_content}: Git diff information from staged changes
๐ ๏ธ Development
Setting Up Development Environment
- Clone the repository:
git clone https://github.com/yumuzhihan/cmai.git
cd cmai
- Create a virtual environment:
uv venv
# Activate virtual environment
# On Unix/macOS:
source .venv/bin/activate
# On Windows:
# .venv\Scripts\activate
- Install development dependencies:
# Install all dependencies including dev dependencies
uv sync --dev
# Or if you prefer to install only production dependencies:
uv sync
Project Structure
cmai/
โโโ cmai/
โ โโโ __init__.py
โ โโโ main.py # CLI entry point
โ โโโ config/
โ โ โโโ __init__.py
โ โ โโโ settings.py # Configuration management
โ โโโ core/
โ โ โโโ __init__.py
โ โ โโโ get_logger.py # Logging utilities
โ โ โโโ normalizer.py # Core normalization logic
โ โโโ providers/
โ โ โโโ __init__.py
โ โ โโโ base.py # Abstract provider interface
โ โ โโโ openai_provider.py # OpenAI-compatible implementation
โ โ โโโ ollama_provider.py # Ollama local model implementation
โ โ โโโ provider_factory.py # Provider factory system
โ โ โโโ bailian_provider.py # Legacy Bailian provider
โ โโโ utils/
โ โโโ __init__.py
โ โโโ git_staged_analyzer.py # Git utilities
โโโ tests/ # Test suite
โโโ docs/ # Documentation
โโโ scripts/ # Utility scripts
โโโ pyproject.toml # Project configuration
โโโ uv.lock # UV lock file
โโโ LICENSE # AGPL-3.0 License
โโโ README.md # This file
Running Tests
python -m pytest tests/
๐ Requirements
- Python 3.10 or higher
- Git (for repository analysis)
- Internet connection (for remote AI provider APIs)
- Ollama installation (for local AI models)
Dependencies
click>=8.2.1- Command-line interfaceopenai>=1.91.0- OpenAI-compatible API clientollama>=0.5.1- Ollama Python client for local modelspydantic>=2.11.7- Data validation and settingspydantic-settings>=2.10.0- Settings management
๐ค Contributing
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Contribution Guidelines
- Follow PEP 8 coding standards
- Add type hints to all functions
- Write comprehensive tests
- Update documentation for new features
- Ensure backward compatibility
- When adding new providers, register them in the provider factory
Adding New Providers
When contributing new AI providers:
- Create a new file in
cmai/providers/(e.g.,custom_provider.py) - Implement the
BaseAIClientinterface - Register the provider in
provider_factory.py - Add configuration examples to the README
- Include tests for the new provider
๐ License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the LICENSE file for details.
๐ Acknowledgments
- Built with Click for the CLI interface
- Uses Pydantic for configuration and data validation
- Supports multiple AI providers including OpenAI, Bailian, DeepSeek, SiliconFlow, and Ollama
- Inspired by conventional commit standards
- Uses UV for fast Python package management
๐ Support
If you encounter any issues or have questions:
- Check the Issues page
- Create a new issue with detailed information about your setup (provider, model, configuration)
- Review the documentation and configuration guide
- For provider-specific issues, include your provider and model information
Common Issues
- "Model must be specified": Ensure you have set the
MODELin your configuration file or passed it as a command-line argument - API key errors: Verify that your API key is correctly set for your chosen provider
- Connection errors: Check your internet connection and API endpoint URLs
- Ollama connection issues: Ensure Ollama is running locally and accessible at the configured host
Note: This tool requires access to AI language models. Please ensure you have appropriate API keys and understand the associated costs before using CMAI in production environments. For local usage, consider using Ollama with open-source models.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cmai-0.2.2.tar.gz.
File metadata
- Download URL: cmai-0.2.2.tar.gz
- Upload date:
- Size: 27.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c009d5e9434c2ca71ba2ae7a9c6226e39a16feae71e1022c44d23e1b6af947f3
|
|
| MD5 |
8cfb2f31c66575cd913dcccf2e8d5e28
|
|
| BLAKE2b-256 |
3365d7b76a63edb543a2aa91e560a3b844de69abf073cf645ab0a19d633f5151
|
File details
Details for the file cmai-0.2.2-py3-none-any.whl.
File metadata
- Download URL: cmai-0.2.2-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
010446a885904098bb81491c79a88a085606be883985a31c831af617361aa7c1
|
|
| MD5 |
8ec30622ab89d45d6a6245a9458f43fb
|
|
| BLAKE2b-256 |
33047f155f28d58629435787dca9b7a5ecd92cf139fc3cee628c30d1174f789d
|