Skip to main content

Contributing to Mellea

Prerequisites: Python 3.11+, uv installed, Ollama installed.

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 the mellea- 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

  1. Fork and clone the repository:

    git clone ssh://git@github.com/<your-username>/mellea.git
    cd mellea/
  2. Create a virtual environment:

    uv venv .venv
    source .venv/bin/activate # On Windows: .venv\Scripts\activate
  3. Install dependencies:

    # Install all dependencies (recommended for development)
    uv sync --all-extras --all-groups

    # Or install only backend dependencies
    uv sync --extra backends --all-groups
  4. Install pre-commit hooks (required):

    pre-commit install

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

  1. Fork and clone the repository:

    git clone ssh://git@github.com/<your-username>/mellea.git
    cd mellea/
  2. Run the installation script:

    conda/install.sh

    The script handles environment setup, dependency installation, and pre-commit hook installation.

Verify the installation

# Start Ollama (required for most tests)
ollama serve

# Run fast tests (skip qualitative tests, ~2 min)
uv run pytest -m "not qualitative"

Coding standards

Type annotations

Type annotations are required on all core functions:

def process_text(text: str, max_length: int = 100) -> str:
"""Process text with maximum length."""
return text[:max_length]

Docstrings

Docstrings serve as prompts — the LLM reads them, so be specific. Use Google-style docstrings:

def extract_entities(text: str, entity_types: list[str]) -> dict[str, list[str]]:
"""Extract named entities from text.

Args:
text: The input text to analyze.
entity_types: List of entity types to extract (e.g., ["PERSON", "ORG"]).

Returns:
Dictionary mapping entity types to lists of extracted entities.

Example:
>>> extract_entities("Alice works at IBM", ["PERSON", "ORG"])
{"PERSON": ["Alice"], "ORG": ["IBM"]}
"""
...

Code style

  • Use Ruff for linting and formatting.
  • Use ... in @generative function bodies.
  • Prefer primitives over classes.
  • Keep functions focused and single-purpose.

Linting and formatting

# Format code
uv run ruff format .

# Lint code
uv run ruff check .

# Fix auto-fixable issues
uv run ruff check --fix .

# Type check
uv run mypy .

Development workflow

Commit messages

Follow Angular commit format:

<type>: <subject>

<body>

<footer>

Types: feat, fix, docs, test, refactor, release

Example:

feat: add support for streaming responses

Implements streaming for all backend types with proper
error handling and timeout management.

Closes #123

Always sign off commits with -s or --signoff:

git commit -s -m "feat: your commit message"

Branch naming: feat/topic, fix/issue-id, docs/topic

AI coding assistants

AI-assisted development is welcome. You are responsible for reviewing and understanding every change before submitting. AI coding assistants that follow project guidelines automatically add an Assisted-by: trailer to commit messages — one line per tool, using its common name (GitHub Copilot, Cursor, etc.):

Assisted-by: Claude Code
Assisted-by: IBM Bob

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

Run hooks manually:

pre-commit run --all-files

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:

git commit -n -m "wip: intermediate work"

Testing

The full test guide lives in test/README.md in the repository — classification rules, marker reference (tier definitions, backend matrix, resource predicates), authoring guide, CI pipeline, and GPU/Ollama operational notes.

Essential commands:

# Install all dependencies (required for tests)
uv sync --all-extras --all-groups

# Start Ollama (required for most tests)
ollama serve

# Fast tests only (no qualitative, ~2 min)
uv run pytest -m "not qualitative"

# Default: includes qualitative, skips slow
uv run pytest

# Replicate CI locally
pre-commit run --all-files
CICD=1 uv run pytest test

Pull request process

  1. Create an issue describing your change (if one does not already exist).
  2. Fork the repository.
  3. Create a branch in your fork using the naming convention above.
  4. Make your changes following the coding standards.
  5. Add tests for new functionality.
  6. Run the test suite to confirm everything passes.
  7. Update documentation as needed.
  8. Push to your fork and open a pull request.
  9. Follow the automated PR workflow instructions in the PR template.

Troubleshooting

ProblemFix
ComponentParseErrorLLM output did not match expected type. Add examples to the docstring.
uv.lock out of syncRun uv sync to update the lock file.
Ollama refused connectionRun ollama serve to start the Ollama server.
ConnectionRefusedError (port 11434)Ollama is not running. Start with ollama serve.
TypeError: missing positional argumentFirst argument to a @generative function must be session m.
Output is wrong or NoneModel too small or prompt insufficient. Try a larger model or add a reasoning field.
error: can't find Rust compilerPython 3.13+ requires Rust for outlines. Install Rust or use Python 3.12.
Tests fail on Intel MacUse conda: conda install 'torchvision>=0.22.0' then uv pip install mellea.
Pre-commit hooks failRun pre-commit run --all-files to see specific issues. Fix them, or use git commit -n to bypass.

Debugging tips

from mellea.core import MelleaLogger

# Enable debug logging
MelleaLogger.get_logger().setLevel("DEBUG")

# Inspect the exact prompt sent to the LLM
print(m.last_prompt())

Contributing to the docs

Documentation lives in docs/docs/. The writing guide at docs/CONTRIBUTING_DOCS.md covers conventions, the PR checklist, and the review process for documentation contributions. Key points:

  • Start body content with H2 — Docusaurus renders the frontmatter title as the page heading; do not repeat it as an H1 in the body.
  • Omit .md extensions from internal links.
  • Tag every fenced code block with a language.
  • Run npx markdownlint-cli2 and fix all warnings before committing.

Getting help


See also: Building Extensions