Files
laya/CONTRIBUTING.md
nefro313andClaude Opus 5.5 96f939dcf2 docs(install): document installing with uv
The README and CONTRIBUTING only showed pip. Add the uv equivalents:
`uv venv` + `uv pip install laya` for a plain environment, `uv add laya`
for a uv project, `--torch-backend` for CPU/GPU PyTorch builds, and the
editable contributor setup. uv environments ship without pip, so
CONTRIBUTING says to use `uv pip install` wherever it says `pip install`.

The repository keeps ignoring uv.lock; nothing here adds a lockfile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:27:29 +05:30

5.5 KiB

Contributing

Thanks for helping improve Laya. This guide keeps reviews fast and the history clean.

By taking part you agree to the Code of Conduct.

Scope

Laya is a fast, local, on-device decision engine. Keep additions in that spirit: they should run in the user's own process or on their own hardware, with no dependency on a hosted service or an external API. A feature that only works against a hosted backend is out of scope for the core package; it belongs in a separate integration or a community project.

Ways to contribute

  • Report a bug with the bug report template.
  • Request or discuss a feature with the feature request template.
  • Improve the docs under docs/, including the hooks guide.
  • Fix a bug or add a feature with a focused pull request.
  • Share benchmarks, evaluations, or integration reports, which the project treats as first class.

Development setup

Laya supports Python 3.10 to 3.13. Use a virtual environment so nothing leaks into your system.

python -m venv .venv
source .venv/bin/activate
pip install -e ".[mcp]"

Optional extras are declared in pyproject.toml: serve, fast, onnx, langchain, langgraph. Install the ones a change needs, for example pip install -e ".[serve]".

If you use uv, the same setup is below. uv environments come without pip, so use uv pip install wherever this guide says pip install.

uv venv --python 3.12
source .venv/bin/activate
uv pip install -e ".[mcp]"

The server and ONNX paths are exercised by tests/test_serve.py and tests/test_onnx.py, which skip when their extras are not installed.

Running the tests

Most suites are plain scripts, so no test runner is required:

python tests/test_router.py
python tests/test_criteria.py
python tests/test_hooks.py
python tests/test_hooks_api.py

A few are pytest based and run with python -m pytest tests/test_serve.py, tests/test_onnx.py and tests/test_truncation_direction.py.

The full set, including the ones the CI runs, is in .github/workflows/ci.yml. A handful of suites need hardware or local weights and are skipped otherwise: tests/test_fast.py needs CUDA, and tests/test_local_e2e.py and tests/test_mcp_local_e2e.py expect checkpoints under ~/laya_models.

Before opening a pull request, run the lint and compile checks the CI runs:

ruff check laya/ --select=E9,F63,F7,F82,F401,F811 --line-length=120
python -m compileall -q laya/ tests/

Documentation

The site at nandhakishorm.github.io/laya builds from docs/ with Zensical, and its API reference builds from the docstrings in laya/. A new page appears under Guides without a config change; to put it somewhere else, add it to docs/.nav.yml. For a docs or docstring change, build the site the way the CI does:

pip install -r requirements-docs.txt
zensical build --strict --clean

The output must have no griffe: lines. Those are docstring problems, such as a parameter the signature does not have, and the CI fails on them.

Style

  • Keep the public API stable. If a change must move it, update tests/test_hooks_api.py in the same pull request, because that suite is the API contract.
  • Prefer the standard library and what is already a dependency over a new one.
  • Leave one runnable check behind for non-trivial logic: an assert based script is enough.
  • Comment only where the code cannot say it, usually a non-obvious reason or a hardware caveat.
  • Match the surrounding style rather than a personal preference.

Commits

Use conventional commit prefixes, matching the history:

feat(agent): ...
fix(router): ...
perf(common): ...
docs(hooks): ...
test(batch): ...

Keep one logical change per commit. A focused pull request is much easier to review and merge than a large one, and it is fine to split a big change into several PRs.

Pull requests

The template asks for four things; filling them in is what makes review quick:

  1. What changed.
  2. Why, ideally the concrete use case, not only the mechanism.
  3. How it was verified: the exact commands you ran.
  4. Any follow-ups you deliberately left out.

Before you open one:

  • Rebase onto the latest main, so the diff is only your change.
  • Keep it focused; split unrelated work into another PR.
  • Update docs or examples when the public API changes.
  • Do not commit secrets, tokens, or large binary files.

If your change moves numbers, report the before and after: the maintainer verifies decisions against real checkpoints, and measured deltas (probability changes, latency, memory) are what gets a change merged.

Reporting issues

The project is maintained in English, so please write issues in English when you can; it is the common language for everyone reading and triaging.

Use the issue templates and include:

  • What you expected and what you got.
  • A minimal reproduction, ideally a short script.
  • Your Laya version (python -c "import laya; print(laya.__version__)"), Python version, OS, and device or backend (CPU, CUDA, MPS, ONNX).

Reviews

Reviewers may ask you to rebase, to split a change, or to add a regression test. Those are the normal asks in this repository, not a rejection. If you disagree with a request, say so on the PR and explain the tradeoff.

License

By contributing you agree that your contributions are licensed under the Apache License 2.0.