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>
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.pyin 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:
- What changed.
- Why, ideally the concrete use case, not only the mechanism.
- How it was verified: the exact commands you ran.
- 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.