Contributing to ChukLLM
February 18, 2026 · View on GitHub
Thank you for your interest in contributing to ChukLLM! We welcome contributions of all kinds, from bug fixes to new features.
Getting Started
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/chrishayuk/chuk-llm.git cd chuk-llm - Install development dependencies:
pip install -e ".[dev]" # or with uv uv sync --dev
Development Setup
Environment Setup
# Create a virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
Running Tests
# Run all tests
make test
# Run specific test file
pytest tests/api/test_conversation.py
# Run with coverage
make test-cov
Code Quality
# Run linting
make lint
# Format code
make format
# Type checking
make typecheck
# Run all checks
make check
Contribution Guidelines
Code Style
- We use
rufffor linting and formatting - Follow PEP 8 with a line length of 100 characters
- Use type hints for all function signatures
- Write docstrings for all public functions and classes
Testing
- Write tests for all new features
- Maintain or improve code coverage
- Test files should mirror the source structure in
tests/ - Use
pytestfixtures for common test setup
Commit Messages
Follow conventional commit format:
type(scope): description
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changestest: Test additions or fixesrefactor: Code refactoringstyle: Code style changesperf: Performance improvementschore: Maintenance tasks
Examples:
feat(conversation): add branching support for conversations
fix(ollama): handle connection errors gracefully
docs(readme): simplify quick start section
Pull Request Process
-
Create a branch for your feature or fix:
git checkout -b feature/your-feature-name -
Make your changes and commit them with clear messages
-
Add tests for new functionality
-
Run checks locally:
make check -
Push to your fork and create a pull request
-
Describe your changes in the PR:
- What problem does it solve?
- What is the approach?
- Any breaking changes?
Adding New Providers
For OpenAI-Compatible Providers
Most modern LLM APIs follow the OpenAI format. Before implementing a custom client, determine the provider's capabilities:
Step 1: Test the API
Use the debug script to understand what the API supports:
# Test function calling capabilities
python examples/debug/debug_openai_compatible_function_calling.py \
--provider yourprovider \
--model your-model-name
The script will test:
- Native OpenAI tools support
- Legacy functions parameter
- JSON mode for function calling
- Tool result message formats (tool/user/function roles)
Step 2: Choose Implementation
Based on debug results:
Option A: Native OpenAI Support (simplest)
# src/chuk_llm/llm/providers/yourprovider_client.py
from .openai_client import OpenAILLMClient
class YourProviderClient(OpenAILLMClient):
"""Simple wrapper - API fully supports OpenAI format"""
pass
Option B: JSON Function Calling Fallback
If the API accepts tools but doesn't call them natively (debug script will tell you):
from .openai_client import OpenAILLMClient
class YourProviderClient(OpenAILLMClient):
"""Uses JSON fallback for function calling"""
# Enable JSON function calling fallback
ENABLE_JSON_FUNCTION_FALLBACK = True
SUPPORTS_TOOL_ROLE = False # Set based on debug results
SUPPORTS_FUNCTION_ROLE = False # Set based on debug results
def __init__(self, model: str, api_key: str, api_base: str | None = None, **kwargs):
super().__init__(model, api_key, api_base, **kwargs)
self.detected_provider = "yourprovider"
Step 3: Add Configuration
Add to src/chuk_llm/chuk_llm.yaml:
yourprovider:
client_class: "chuk_llm.llm.providers.yourprovider_client:YourProviderClient"
api_key_env: "YOURPROVIDER_API_KEY"
api_base: "https://api.yourprovider.com/v1"
default_model: "your-default-model"
models: ["*"]
Step 4: Add Examples
Create examples/providers/yourprovider_usage_examples.py following existing patterns.
Step 5: Test
# Run your examples
python examples/providers/yourprovider_usage_examples.py
# Run tests
pytest tests/llm/providers/test_yourprovider_client.py
See examples/debug/README.md for detailed debug script documentation.
For Custom Providers
For providers with completely different APIs (non-OpenAI-compatible):
- Create a new client in
src/chuk_llm/llm/providers/ - Inherit from
BaseLLMClient - Implement required methods:
create_completion(), streaming support - Add provider configuration to
chuk_llm.yaml - Add tests in
tests/llm/providers/ - Update documentation
Example structure:
# src/chuk_llm/llm/providers/newprovider_client.py
from chuk_llm.llm.core.base import BaseLLMClient
class NewProviderClient(BaseLLMClient):
def __init__(self, api_key: str = None, **kwargs):
super().__init__(provider="newprovider", **kwargs)
# Initialize client
async def create_completion(self, messages, tools=None, **kwargs):
# Implement completion logic
pass
Adding New Features
Before adding a major feature:
- Open an issue to discuss the feature
- Get feedback from maintainers
- Design the API with examples
- Implement incrementally with tests
Project Structure
chuk-llm/
├── src/chuk_llm/
│ ├── api/ # Public API layer
│ ├── llm/ # LLM client implementations
│ ├── configuration/ # Config management
│ └── cli.py # CLI implementation
├── tests/ # Test suite
├── examples/ # Usage examples
├── docs/ # Documentation
└── benchmarks/ # Performance benchmarks
Getting Help
- 💬 Discussions - Ask questions
- 🐛 Issues - Report bugs
Recognition
Contributors will be recognized in:
- The project README
- Release notes
- GitHub contributors page
Thank you for helping make ChukLLM better! 🎉