Skip to main content

AI-powered pre-commit hook for code review using Google Gemini

Project description

Solvent

AI-powered pre-commit hook for automated code review using Google Gemini. Solvent automatically reviews your staged files before committing, blocking commits with critical issues while providing actionable suggestions for improvement.

Features

  • Automated Pre-commit Reviews: Seamlessly integrates with git pre-commit hooks
  • AI-Powered Analysis: Uses Google Gemini for intelligent code review
  • Smart Blocking: Blocks commits with critical issues (security vulnerabilities, dangerous operations, critical bugs)
  • Actionable Feedback: Provides suggestions for non-critical improvements without blocking commits
  • Multi-file Support: Handles multiple staged files in a single review
  • Configurable Ignore Patterns: Exclude files from review using .solventignore (gitignore-style patterns)
  • File-Specific Context: Provide custom AI context per file/directory using .solventrules
  • File Size Limits: Automatically skips files larger than the configured limit (default: 1MB) to prevent API issues
  • BDD Testing: Comprehensive test coverage using behave

Installation

From PyPI (Recommended)

Install Solvent from PyPI:

pip install solvent-ai

Or using uv:

uv pip install solvent-ai

From Source

This project uses uv for fast and reliable dependency management.

# Clone the repository
git clone https://github.com/mbocevski/solvent.git
cd solvent

# Install dependencies
uv sync

# Install with dev dependencies (for development)
uv sync --group dev

# Install the package in development mode
uv pip install -e .

Configuration

Environment Variables

Solvent uses environment variables for configuration. All settings use the SOLVENT_ prefix and are case-insensitive.

Required:

export SOLVENT_GEMINI_API_KEY="your-api-key-here"

Optional:

export SOLVENT_GEMINI_MODEL="gemini-2.5-flash"  # Default: gemini-2.5-flash
export SOLVENT_GEMINI_TEMPERATURE="0.7"         # Default: 0.7 (range: 0.0-2.0)
export SOLVENT_LOG_LEVEL="INFO"                 # Default: INFO
export SOLVENT_MAX_FILE_SIZE="1048576"          # Default: 1MB (in bytes)

Note: Get your Gemini API key from Google AI Studio.

Ignore Patterns (.solventignore)

Create a .solventignore file in your repository root to exclude files from AI review. Uses gitignore-style pattern matching, powered by the pathspec library.

Example .solventignore:

# Ignore log files
*.log
*.tmp

# Ignore build artifacts
build/
dist/
*.egg-info/

# Ignore vendor and dependency directories
vendor/
node_modules/
.venv/

# Ignore specific paths
/temp_dir/
**/cache/

Behavior:

  • Files matching these patterns are excluded from review
  • The pre-commit hook passes automatically if all staged files are ignored
  • Patterns support all gitignore-style syntax (wildcards, negation, etc.)
  • Patterns are evaluated relative to the repository root

Context Rules (.solventrules)

Create a .solventrules file in your repository root to provide custom context to the AI for specific files or directories. This helps the AI understand your project structure and provide more relevant, context-aware reviews.

File Format:

The .solventrules file uses an INI-style format:

[pattern]
context = Context description for matching files

[another/pattern/**]
context = Different context for other files

Example .solventrules:

# Test files - focus on test quality and coverage
[tests/**]
context = This is test code. Focus on test quality, coverage, edge cases, and correctness.

# Documentation - focus on clarity and completeness
[docs/**]
context = This is documentation. Focus on clarity, grammar, completeness, and accuracy.

# Production code - be strict about security and performance
[src/**]
context = This is production code. Be strict about security, performance, and best practices.

# API endpoints - check for security vulnerabilities
[src/api/**]
context = This is API code. Check for security vulnerabilities, input validation, error handling, and authentication.

# Configuration files - check for secrets
[*.config]
[*.env]
context = This is a configuration file. Check for hardcoded secrets, credentials, and security issues.

Pattern Matching:

  • Uses gitignore-style patterns (same syntax as .solventignore)
  • Supports wildcards: *.py, **/tests/, src/**
  • First matching rule wins (order matters - place more specific patterns first)
  • Patterns are evaluated relative to the repository root

Benefits:

  • Test files: Reviewed with test-specific criteria (coverage, edge cases)
  • Documentation: Gets grammar and clarity checks
  • Production code: Receives stricter security and performance reviews
  • Configuration files: Gets secret and credential detection
  • Custom contexts: Tailor reviews to your project's specific needs

Usage

Command Line

After setting your SOLVENT_GEMINI_API_KEY environment variable:

# Review staged files
uv run solvent

# Or if installed globally
solvent

The command will:

  • Exit with code 0 if the review passes
  • Exit with code 1 if critical issues are found
  • Print detailed feedback to stdout

Programmatic Usage

from solvent import run_pre_commit_review

# Run the pre-commit review
result = run_pre_commit_review()

if not result.passed:
    print("Pre-commit check failed!")
    print(result.feedback)
    exit(1)
else:
    print("Pre-commit check passed!")
    if result.feedback:
        print(result.feedback)  # Suggestions for improvement

Integration with pre-commit Framework

Solvent integrates seamlessly with the pre-commit framework. Add the following to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/mbocevski/solvent
    rev: v0.1.1 # Use a specific version tag
    hooks:
      - id: solvent
        verbose: true # Always show output to see the AI response when status Passed

Then install the hooks:

pre-commit install

The hook will automatically install Solvent and its dependencies when first run.

Note: By default, pre-commit only shows output from hooks that fail. Add verbose: true to the hook configuration to always see AI feedback, even when the review passes. This is useful for seeing suggestions and improvements.

Alternative: Local Hook (For Development)

If you're developing Solvent or want to use a local installation:

# Install Solvent first
pip install solvent-ai
# Or: uv add solvent-ai

Then use a local hook in .pre-commit-config.yaml:

repos:
  - repo: local
    hooks:
      - id: solvent
        name: Solvent AI Code Review
        entry: solvent # or: uv run solvent
        language: system
        pass_filenames: false
        always_run: true

Important: Make sure to set the SOLVENT_GEMINI_API_KEY environment variable before running pre-commit hooks. You can set it in your shell profile or use a tool like direnv for project-specific environment variables.

How It Works

Solvent follows a streamlined workflow to review your code:

  1. Detects Staged Files: Scans the git repository for all files staged for commit
  2. Applies Ignore Patterns: Filters out files matching .solventignore patterns (if present)
  3. Checks File Sizes: Skips files larger than the configured size limit (default: 1MB) to prevent API token limits and timeouts
  4. Loads Context Rules: Loads file-specific context from .solventrules (if present)
  5. Reads File Contents: Reads the contents of non-ignored, size-appropriate staged files (skips binary files, files with encoding errors, and oversized files)
  6. AI Review: Sends files to Google Gemini for review, including file-specific context where applicable
  7. Determines Pass/Fail: Analyzes AI feedback for critical issues using:
    • Machine-readable status block (preferred)
    • Keyword-based fallback detection
  8. Returns Result: Returns HookResult with pass/fail status and detailed feedback

Critical Issues That Block Commits

The following issues will cause the pre-commit hook to fail:

  • Security Vulnerabilities: SQL injection, XSS, code injection, remote code execution, etc.
  • Dangerous Operations: Unintended file deletion, system command execution, unsafe file operations
  • Critical Bugs: Issues that could cause data loss, system failures, or production outages
  • Unsafe Code Patterns: Code that introduces significant risk or violates safety requirements
  • Hardcoded Secrets: Credentials, API keys, or sensitive information in code

Non-Critical Issues

The following issues will be reported but will not block the commit:

  • Code style violations (formatting, naming conventions)
  • Minor code quality improvements (refactoring opportunities)
  • Performance optimizations that don't affect correctness
  • Documentation improvements
  • Best practice suggestions that don't introduce immediate risk

These suggestions are included in the feedback to help improve code quality over time without blocking your workflow.

Examples

Example 1: Basic Usage

# Set your API key
export SOLVENT_GEMINI_API_KEY="your-api-key"

# Stage some files
git add src/app.py tests/test_app.py

# Run review
uv run solvent

# Output will show:
# - Status (PASS/FAIL)
# - Critical issues (if any)
# - Suggestions for improvement

Example 2: Using .solventignore

Create .solventignore in your repository root:

# Ignore build artifacts
*.log
*.tmp
build/
dist/
.venv/

# Ignore vendor dependencies
vendor/
node_modules/

Now when you commit, these files are automatically excluded from review. If all staged files match ignore patterns, the hook passes immediately without calling the AI.

Example 3: Using .solventrules

Create .solventrules in your repository root:

[tests/**]
context = This is test code. Focus on test quality, coverage, and edge cases.

[src/api/**]
context = This is API code. Check for security vulnerabilities, input validation, and error handling.

[docs/**]
context = This is documentation. Focus on clarity, completeness, and accuracy.

The AI will now provide context-aware reviews:

  • Test files: Reviewed for test quality, coverage, and correctness
  • API files: Security-focused reviews with emphasis on vulnerabilities
  • Documentation: Grammar and clarity checks

Example 4: Combined Usage

Use both .solventignore and .solventrules together for maximum control:

.solventignore:

*.log
build/
dist/

.solventrules:

[src/**]
context = Production code - be strict about security and performance

[tests/**]
context = Test code - focus on quality and coverage

Result:

  • Log files and build artifacts are ignored (not reviewed)
  • Source files get strict security and performance reviews
  • Test files get quality-focused reviews
  • Other files get default reviews

Project Structure

solvent/
├── src/solvent/
│   ├── __init__.py              # Main package exports
│   ├── main.py                  # CLI entry point
│   ├── hook/
│   │   ├── __init__.py          # Hook module exports
│   │   ├── orchestrator.py      # Pre-commit hook orchestration
│   │   └── evaluator.py         # Pass/fail evaluation logic
│   ├── ai/
│   │   ├── __init__.py          # AI module exports
│   │   ├── gemini_client.py     # Google Gemini API integration
│   │   └── context.py           # AI prompt context and templates
│   ├── config/
│   │   ├── __init__.py          # Config module exports
│   │   ├── logging_config.py    # Logging setup and configuration
│   │   └── settings.py          # Application settings (pydantic)
│   ├── git/
│   │   ├── __init__.py          # Git module exports
│   │   └── repository.py        # Git operations (staged files, etc.)
│   ├── rules/
│   │   ├── __init__.py          # Rules module exports
│   │   ├── ignore.py            # .solventignore pattern handling
│   │   └── context.py           # .solventrules context rule handling
│   └── models/
│       ├── __init__.py          # Models module exports
│       └── hook.py              # HookResult data model
├── features/                    # BDD feature files (behave)
│   ├── environment.py           # Behave environment setup/teardown
│   ├── git_commit_review.feature
│   ├── config_rules.feature
│   └── steps/
│       ├── git_commit_review_steps.py
│       └── config_rules_steps.py
└── pyproject.toml               # Project configuration and dependencies

Development

Prerequisites

  • Python >= 3.10
  • uv for dependency management
  • Google Gemini API key (for running tests)

Running Tests

This project uses behave for Behavior-Driven Development (BDD) testing.

# Run all tests
uv run behave

# Dry run (see what would be executed without running)
uv run behave --dry-run

# Run with specific output format
uv run behave --format json
uv run behave --format json.pretty

# Run specific feature
uv run behave features/config_rules.feature

Code Quality

We use ruff for linting and formatting, and pyright for type checking:

# Run linter
uv run ruff check src/solvent

# Auto-fix linting issues
uv run ruff check --fix src/solvent

# Format code
uv run ruff format

# Type checking
uv run pyright src/solvent

# Run all quality checks
uv run ruff check src/solvent && uv run ruff format && uv run pyright src/solvent

Development Workflow

  1. Create a feature branch
  2. Make your changes
  3. Write or update tests
  4. Run tests: uv run behave
  5. Check code quality: uv run ruff check --fix && uv run pyright
  6. Format code: uv run ruff format
  7. Commit your changes

Requirements

  • Python: >= 3.10
  • Google Gemini API Key: Required for AI reviews (Get one here)
  • Git Repository: Solvent operates on git repositories
  • Dependencies: Automatically installed via uv sync:
    • google-genai: Google Gemini API client
    • GitPython: Git repository operations
    • pydantic / pydantic-settings: Configuration management
    • pathspec: Pattern matching for ignore/rules files

Troubleshooting

API Key Issues

Error: "AI review authentication failed" or "API key not valid"

  • Ensure SOLVENT_GEMINI_API_KEY is set in your environment
  • Verify the API key is correct and not expired
  • Check that the API key has the necessary permissions for the Gemini API
  • Get a new API key from Google AI Studio

Error: "AI review permission denied"

  • Your API key may not have the required permissions
  • Check your Google Cloud project settings
  • Ensure the Gemini API is enabled in your project

Rate Limiting

Error: "AI review service rate limit exceeded"

  • The Gemini API has rate limits based on your usage tier
  • Wait a few moments and try again
  • Consider upgrading your API quota if you frequently hit limits
  • The hook automatically retries with exponential backoff (up to 3 attempts)

Service Unavailable

Error: "AI review service is temporarily unavailable"

  • The Gemini API service may be experiencing downtime
  • The hook automatically retries transient errors (503, 502, 504)
  • Wait a few moments and try again
  • Check Google Cloud Status for service issues

No Files to Review

Message: "No staged files to review"

  • Ensure you have files staged with git add
  • Run git status to verify staged files
  • The hook only reviews files that are staged for commit

Message: "All staged files are ignored"

  • Check your .solventignore file for patterns that might be too broad
  • Verify the patterns match what you expect
  • Files matching .solventignore patterns are excluded from review

Message: "All staged files were skipped (too large, binary, or unreadable)"

  • Files larger than the configured size limit (default: 1MB) are skipped
  • Binary files and files with encoding errors are skipped
  • Adjust SOLVENT_MAX_FILE_SIZE if you need to review larger files
  • Note: Very large files may hit API token limits

Git Repository Issues

Error: "Error accessing git repository"

  • Ensure you're running solvent from within a git repository
  • Run git status to verify you're in a valid repository
  • Check that .git directory exists and is accessible

Configuration Issues

Settings not being applied

  • Environment variables must use the SOLVENT_ prefix
  • Variable names are case-insensitive
  • Restart your terminal/shell after setting environment variables
  • Use echo $SOLVENT_GEMINI_API_KEY to verify the variable is set

Log level not changing

  • Ensure SOLVENT_LOG_LEVEL is set to one of: DEBUG, INFO, WARNING, ERROR, CRITICAL
  • Check that the variable is exported: export SOLVENT_LOG_LEVEL=DEBUG
  • Run with SOLVENT_LOG_LEVEL=DEBUG uv run solvent to test

File Reading Issues

Files are being skipped unexpectedly

  • Check file encoding (only UTF-8 text files are reviewed)
  • Verify file permissions (must be readable)
  • Ensure files exist and are not symlinks to non-existent files
  • Binary files are automatically skipped

Getting More Information

Enable debug logging:

export SOLVENT_LOG_LEVEL=DEBUG
uv run solvent

This will show detailed information about:

  • Which files are being reviewed
  • Which files are being skipped and why
  • API request/response details
  • Retry attempts

Check version:

uv run solvent --version

Get help:

uv run solvent --help

License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solvent_ai-0.1.1.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

solvent_ai-0.1.1-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file solvent_ai-0.1.1.tar.gz.

File metadata

  • Download URL: solvent_ai-0.1.1.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for solvent_ai-0.1.1.tar.gz
Algorithm Hash digest
SHA256 119666430b050df3510f99232534744bcfe067eb281ebc44f27b17e6b9fa9eb0
MD5 d92b56d2645106d2325a0ff7cdf28be7
BLAKE2b-256 6da4a8b5c282802ac3429018ba9f5668c09901f15002d515645bc749be655601

See more details on using hashes here.

Provenance

The following attestation bundles were made for solvent_ai-0.1.1.tar.gz:

Publisher: publish.yml on mbocevski/solvent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file solvent_ai-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: solvent_ai-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 28.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for solvent_ai-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 798aa3416025bcf24dbc33deecbb2586b35246ee4ebd17f0c6d884a5828f3e9c
MD5 c56871d196ead0440cb0aff36d8fd0fe
BLAKE2b-256 4fba5ff5f7d19e6b289699d67a6abcbfe3729dec5ef30bedc9a62caa7229e423

See more details on using hashes here.

Provenance

The following attestation bundles were made for solvent_ai-0.1.1-py3-none-any.whl:

Publisher: publish.yml on mbocevski/solvent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page