Thank you for your interest in contributing to Council AI! This document provides guidelines and instructions for contributing.
- Clone the repository
git clone https://github.com/doronpers/council-ai.git
cd council-ai- Upgrade pip (recommended)
pip install --upgrade pip- Install in development mode
pip install -e ".[dev]"- Run tests
pytestNote
On Windows, if tools like black, ruff, or pytest are not in your PATH, you can run them via the python module syntax:
python -m black src/
python -m ruff check src/
python -m pytestcouncil-ai/
├── src/council_ai/ # Main package
│ ├── cli/ # CLI implementation
│ ├── core/ # Core functionality
│ ├── domains/ # Domain configurations
│ ├── personas/ # Persona YAML files
│ └── providers/ # LLM provider implementations
├── tests/ # Test suite
├── examples/ # Example scripts
└── pyproject.toml # Package configuration
Create a YAML file in src/council_ai/personas/:
id: your_persona
name: Full Name
title: Brief Title
emoji: '🎭'
category: advisory # or adversarial, creative, analytical, strategic, operational
core_question: 'The fundamental question this persona asks?'
razor: 'Their decision-making principle.'
traits:
- name: Trait Name
description: What this trait means
weight: 1.5 # 0.0-2.0, affects influence
focus_areas:
- Area 1
- Area 2
- Area 3Edit src/council_ai/domains/__init__.py and add to the DOMAINS dictionary:
"your_domain": Domain(
id="your_domain",
name="Display Name",
description="What this domain is for",
category=DomainCategory.BUSINESS, # or TECHNICAL, CREATIVE, PERSONAL, GENERAL
default_personas=["persona1", "persona2", "persona3"],
example_queries=[
"Example question 1",
"Example question 2",
],
),Create a class in src/council_ai/providers/__init__.py:
class YourProvider(LLMProvider):
"""Your LLM provider."""
def __init__(self, api_key: Optional[str] = None):
super().__init__(api_key or os.environ.get("YOUR_API_KEY"))
if not self.api_key:
raise ValueError("API key required")
async def complete(
self,
system_prompt: str,
user_prompt: str,
max_tokens: int = 1000,
temperature: float = 0.7,
) -> str:
# Your implementation
pass
# Register it
_PROVIDERS["your_provider"] = YourProviderAdd tests to tests/test_core.py or create new test files:
def test_your_feature():
"""Test description."""
# Arrange
council = Council(api_key="test-key")
# Act
result = council.some_method()
# Assert
assert result == expected_valueRun tests:
pytest -v
pytest tests/test_core.py::test_your_featureWe use:
- Black for code formatting (line length: 100)
- Ruff for linting
- Type hints for better code clarity
Format your code:
black src/
ruff check src/-
Fork the repository and create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes following the code style
-
Add tests for new functionality
-
Run tests to ensure everything passes
pytest
-
Update documentation if needed
- README.md for user-facing changes
- Docstrings for code changes
-
Commit your changes
git add . git commit -m "Add: brief description of your changes"
-
Push and create a Pull Request
git push origin feature/your-feature-name
Use clear, descriptive commit messages:
Add: new feature or fileFix: bug fixUpdate: modify existing featureRefactor: code restructuringDocs: documentation changesTest: add or modify tests
- Open an issue for bugs or feature requests
- Start a discussion for questions or ideas
- Check existing issues before creating new ones
By contributing, you agree that your contributions will be licensed under the MIT License.