Contribution pathways
Three pathways exist for contributing to Mellea: Core repository — bug fixes, standard library additions (Requirements, Components, Sampling Strategies), backend improvements, documentation, and tests. Follow the Pull request process below. Applications and libraries — build tools or applications on top of Mellea in your own repository. Use themellea- prefix for discoverability (e.g., github.com/my-company/mellea-legal-utils).
Community components — contribute experimental or specialized components to mellea-contribs. Open an issue first for general-purpose additions to decide whether they belong in the standard library or in mellea-contribs.
Development setup
Set up with uv (recommended)
-
Fork and clone the repository:
-
Create a virtual environment:
-
Install dependencies:
-
Install pre-commit hooks (required):
Note: Python 3.13+ requires a Rust compiler for the outlines dependency. Use Python 3.12 if you prefer to avoid this.
Set up with conda or mamba
-
Fork and clone the repository:
-
Run the installation script:
The script handles environment setup, dependency installation, and pre-commit hook installation.
Verify the installation
Coding standards
Type annotations
Type annotations are required on all core functions:Docstrings
Docstrings serve as prompts — the LLM reads them, so be specific. Use Google-style docstrings:Code style
- Use Ruff for linting and formatting.
- Use
...in@generativefunction bodies. - Prefer primitives over classes.
- Keep functions focused and single-purpose.
Linting and formatting
Development workflow
Commit messages
Follow Angular commit format:feat, fix, docs, test, refactor, release
Example:
-s or --signoff:
feat/topic, fix/issue-id, docs/topic
Pre-commit hooks
Pre-commit hooks run automatically before each commit and check:- Ruff — linting and formatting
- mypy — type checking
- uv-lock — dependency lock file sync
- codespell — spell checking
Warning: pre-commit --all-files may take several minutes. Do not cancel mid-run as it can corrupt state.
Use the -n flag to bypass hooks for intermediate work-in-progress commits:
Testing
Test markers
Tests use a four-tier granularity system. Every test belongs to exactly one tier:| Tier | When to use | How to apply |
|---|---|---|
unit | Self-contained, no services, no I/O | Auto-applied — never write @pytest.mark.unit |
integration | Real SDK/library boundary or multi-component wiring | @pytest.mark.integration |
e2e | Real backends (Ollama, APIs, GPU models), deterministic assertions | @pytest.mark.e2e + backend marker(s) |
qualitative | Subset of e2e with non-deterministic output assertions | @pytest.mark.qualitative per-function, e2e + backend at module level |
| Marker | Backend | Resources |
|---|---|---|
ollama | Ollama (port 11434) | Local, light (~2–4 GB RAM) |
openai | OpenAI API or compatible | API calls (may use Ollama /v1) |
watsonx | Watsonx API | API calls, requires credentials |
huggingface | HuggingFace transformers | Local, GPU required |
litellm | LiteLLM (wraps other backends) | Depends on underlying backend |
bedrock | AWS Bedrock | API calls, requires credentials |
test/predicates.py, for e2e/qualitative tests):
| Predicate | Use when test needs |
|---|---|
require_gpu() | Any GPU (CUDA or MPS) |
require_gpu(min_vram_gb=N) | GPU with at least N GB VRAM |
require_ram(min_gb=N) | N GB+ system RAM |
require_api_key("ENV_VAR") | Specific API credentials |
require_package("pkg") | Optional dependency |
require_python((3, 11)) | Minimum Python version |
| Marker | Purpose |
|---|---|
slow | Tests taking >1 minute (excluded by default) |
qualitative | Non-deterministic output (skipped when CICD=1) |
Running tests
Timing expectations
| Run | Duration |
|---|---|
Fast tests (-m "not qualitative") | ~2 minutes |
| Default (qualitative, no slow) | Several minutes |
Slow tests (-m slow) | More than 1 minute |
| Pre-commit hooks | 1–5 minutes |
Replicate CI locally
Pull request process
- Create an issue describing your change (if one does not already exist).
- Fork the repository.
- Create a branch in your fork using the naming convention above.
- Make your changes following the coding standards.
- Add tests for new functionality.
- Run the test suite to confirm everything passes.
- Update documentation as needed.
- Push to your fork and open a pull request.
- Follow the automated PR workflow instructions in the PR template.
Troubleshooting
| Problem | Fix |
|---|---|
ComponentParseError | LLM output did not match expected type. Add examples to the docstring. |
uv.lock out of sync | Run uv sync to update the lock file. |
Ollama refused connection | Run ollama serve to start the Ollama server. |
ConnectionRefusedError (port 11434) | Ollama is not running. Start with ollama serve. |
TypeError: missing positional argument | First argument to a @generative function must be session m. |
| Output is wrong or None | Model too small or prompt insufficient. Try a larger model or add a reasoning field. |
error: can't find Rust compiler | Python 3.13+ requires Rust for outlines. Install Rust or use Python 3.12. |
| Tests fail on Intel Mac | Use conda: conda install 'torchvision>=0.22.0' then uv pip install mellea. |
| Pre-commit hooks fail | Run pre-commit run --all-files to see specific issues. Fix them, or use git commit -n to bypass. |
Debugging tips
Contributing to the docs
Documentation lives indocs/docs/. The writing guide at
docs/docs/guide/CONTRIBUTING covers conventions, the PR
checklist, and the review process for documentation contributions. Key points:
- Start body content with H2 — Mintlify renders the frontmatter
titleas the page heading. - Omit
.mdextensions from internal links. - Tag every fenced code block with a language.
- Run
npx markdownlint-cli2and fix all warnings before committing.
Getting help
- Check existing issues
- Join the Github Discussions
- Open a new issue with the appropriate label
See also: Building Extensions