Thank you for your interest in contributing to MultiMind SDK! This document provides guidelines and instructions for contributing to the project.
- Code of Conduct
- Getting Started
- Development Setup
- Good First Areas
- Contribution Workflow
- Code Style and Standards
- Testing
- Documentation
- Pull Request Process
- Feature Requests and Bug Reports
- Community
- CLI Testing Guidelines
By participating in this project, you agree to abide by our Code of Conduct. Please read it before contributing.
- Fork the repository
- Clone your fork:
git clone https://github.com/your-username/multimind-sdk.git cd multimind-sdk - Add the upstream repository:
git remote add upstream https://github.com/multimindlab/multimind-sdk.git
-
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install development dependencies + pre-commit hooks in one shot:
make install
If you don't have GNU
make, the equivalent two commands are:pip install -e ".[dev]" pre-commit install -
(Optional) Install every extras group for end-to-end work on RAG, agents, compliance, fine-tuning, etc.:
make install-all
| Command | What it does |
|---|---|
make help |
Show every target with a one-line description. |
make test |
Run tests excluding integration, requires_api_key, slow markers. |
make test-all |
Run the full test suite. |
make lint |
ruff check + ruff format --check (no file mutation). |
make format |
ruff check --fix + ruff format (mutates files). |
make typecheck |
Run mypy (advisory — typing migration is in progress). |
make clean |
Remove build artifacts and tool caches. |
make build |
Build sdist + wheel into dist/. |
pre-commit install wires the hooks in .pre-commit-config.yaml into
git commit. They run automatically on every commit and currently cover:
- Whitespace / EOF / merge-conflict / private-key / large-file checks
ruff check --fix(lints + safe auto-fixes)ruff format(formatter — replaces black; settings in[tool.ruff.format])
Mypy is not in pre-commit yet — see the comment in
.pre-commit-config.yaml for the rationale. Use make typecheck to run it
manually.
If a hook modifies files (e.g. ruff --fix cleans an import), the commit
fails with a clear message. Re-run git add for the modified files and
commit again.
Approachable places to make a genuinely useful first contribution:
- Examples (
examples/) — small, runnable scripts demonstrating one feature. Several offline examples (examples/compliance/guarded_model.py, examples/observability/cost_tracking.py, examples/evaluation/hallucination_detection.py) show the pattern; a new example needs no deep knowledge of the internals. - Documentation (
docs/, README, this file) — fixing inaccuracies, adding recipes to docs/cookbook.md, or improving the non-technical guide. If a doc confused you, that confusion is the bug report. - Vector-store backends (
multimind/vector_store/) — many of the 40+ backends are client-backed stubs whose methods stillraise NotImplementedError(e.g.cassandra.py,azuresearch.py,clickhouse.py,tiledb.py). Picking one and implementing its methods against the real client library is self-contained: the interface to satisfy is inmultimind/vector_store/base.py, and working references include the FAISS and Chroma backends.
Also check issues labeled good first issue on
GitHub.
-
Create a new branch for your feature/fix:
git checkout -b feature/your-feature-name # or git checkout -b fix/your-fix-name -
Make your changes following our code style guidelines
-
Run tests and ensure they pass:
pytest
-
Commit your changes:
git commit -m "Description of your changes" -
Push to your fork:
git push origin feature/your-feature-name
-
Create a Pull Request from your fork to the main repository
- Follow PEP 8 guidelines
- Use type hints for all function parameters and return values
- Document all public functions, classes, and methods using docstrings
- Maximum line length: 100 characters (configured in
[tool.ruff])
We standardize on a single tool — Ruff — for linting, import sorting,
and formatting. There is no separate black / isort / flake8 step.
ruff check— lint + import sorting (replaces flake8 + isort)ruff format— code formatter (replaces black)mypy— type checking (advisory; opt-in viamake typecheck)
Run them via the Makefile (recommended):
make format # auto-fix + reformat (mutates files)
make lint # check only (no file changes)
make typecheck # advisory mypy runOr invoke ruff directly:
ruff check multimind/ # report lint issues
ruff check multimind/ --fix # apply safe auto-fixes
ruff format multimind/ # apply formatterAll settings live in pyproject.toml under [tool.ruff] and
[tool.ruff.format] — single source of truth for CI, pre-commit, and
local runs.
- Use Google-style docstrings
- Include examples in docstrings where appropriate
- Keep documentation up-to-date with code changes
- Write tests for all new features and bug fixes
- Use pytest for testing
- Place tests in the
tests/directory - Follow the naming convention:
test_*.py - Include both unit tests and integration tests
Example test structure:
def test_feature_name():
# Arrange
setup_code()
# Act
result = function_to_test()
# Assert
assert result == expected_valueRun all tests:
pytestRun specific test file:
pytest tests/test_file.pyRun with coverage:
pytest --cov=multimind- Document all public APIs
- Include type hints
- Provide clear examples
- Update docstrings when changing code
- Update README.md for significant changes
- Add/update docstrings for new features
- Include usage examples
- Document configuration options
- Ensure your code follows our style guidelines
- Update documentation for any new features
- Add tests for new functionality
- Ensure all tests pass
- Update the changelog
- Fill out the PR template
- Request review from maintainers
## Description
[Describe your changes here]
## Related Issues
[Link to related issues]
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring
## Checklist
- [ ] Code follows style guidelines
- [ ] Documentation updated
- [ ] Tests added/updated
- [ ] All tests pass
- [ ] Changelog updated- Check existing issues to avoid duplicates
- Use the feature request template
- Provide clear description and use cases
- Include potential implementation ideas
- Use the bug report template
- Include steps to reproduce
- Provide expected and actual behavior
- Include environment details
- Add error messages and logs
- GitHub Issues: For bug reports and feature requests
- GitHub Discussions: For general discussions
- Discord: For real-time communication
- Email: For private matters
- Check the documentation
- Search existing issues
- Join our Discord community
- Ask in GitHub Discussions
- Contributors will be listed in the README
- Significant contributions will be highlighted in release notes
- Active contributors may be invited to join the maintainer team
All new CLI features or changes must include corresponding tests in tests/test_cli.py.
- Use
pytestandpytest-mockfor mocking SDK and external dependencies. - Use
click.testing.CliRunnerto invoke CLI commands and check outputs. - Test both success and failure cases, including edge cases and user prompts.
- For destructive actions (like
delete), test both confirmation and abort scenarios.
from click.testing import CliRunner
from multimind.cli import cli
def test_train_help():
runner = CliRunner()
result = runner.invoke(cli, ['train', '--help'])
assert result.exit_code == 0
assert "Fine-tune a model" in result.output
def test_train_with_mock(mocker):
runner = CliRunner()
mock_tuner = mocker.patch('multimind.cli.UniPELTTuner')
instance = mock_tuner.return_value
instance.train.return_value = None
result = runner.invoke(cli, ['train', '--config', 'dummy.yaml'])
assert result.exit_code == 0 or result.exit_code == 1
instance.train.assert_called()See tests/test_cli.py for more comprehensive examples.
Thank you for contributing to MultiMind SDK! Your help makes the project better for everyone.