Contributing
Set up a development checkout of NeMo Labs Voice Agent, satisfy the automated gates, and prepare a pull
request for merge. The authoritative source is CONTRIBUTING.md at the repository root. This page summarizes
that file and links to related documentation.
Development Environment
The development environment has the following requirements:
Clone and bootstrap:
install.sh does more than uv sync. It installs npm, nodejs, build-essential, and python3-dev.
The cdifflib transitive dependency is source-distribution-only and compiles from source. The script also
installs uv if needed, runs uv sync, and prefetches two Natural Language Toolkit (NLTK) corpora for the
Apache-2.0 grapheme-to-phoneme (G2P) fallback. Prefer it to a bare uv sync on a new system.
Then add the test tools and Git hooks:
Run subsequent commands through uv run, or activate the virtual environment for the current shell session
with source .venv/bin/activate. Review these constraints:
- Do not run
uv syncinside an active non-baseConda environment.install.shexits early whenCONDA_DEFAULT_ENVis set to anything other thanbase. Conda’sgcccombined with system Python headers breaks C extensions. Runconda deactivatefirst. - The default install pulls CUDA 13.0 wheels (
torch-backend = "cu130"under[tool.uv]). Edit that key inpyproject.tomlbefore syncing if you needcu128,cu124, or CPU-only. Refer to Installation.
Code Style
Ruff is the only formatter and linter in this repository. black and isort are not installed and are
not dependencies—do not add them or reformat files with them. Configuration lives in ruff.toml:
Run it on the paths you touched:
Or run the full hook set the way CI does:
.pre-commit-config.yaml configures ruff with --fix, a second ruff pass restricted to --select I, and
ruff-format, plus check-yaml, check-case-conflict, detect-private-key, check-added-large-files
with --maxkb=1000, and requirements-txt-fixer. The lint-check job in
.github/workflows/cicd-main.yml runs pre-commit run --all-files and blocks the rest of the continuous
integration (CI) pipeline on failure.
License Headers
Every .py file needs an SPDX and Apache-2.0 header in its first lines. .github/workflows/copyright-check.yml
runs on every pull request and fails without it. Copy the header from any existing module. Markdown and
YAML are not checked, but repository convention is to include one anyway.
Running Tests
Suites live in tests/unit/ and tests/functional/. There are no test modules directly under tests/.
Markers declared in pyproject.toml: unit, functional, gpu, slow, skipduringci, pleasefixme.
CI’s unit lane deselects pleasefixme. The functional lane runs on H100 runners. Refer to
Testing for the full suite layout and how to write new tests.
Commits
Use conventional-commit subjects, as documented in CONTRIBUTING.md:
Types: feat, fix, docs, style, refactor, test, chore.
Sign-Off (DCO) — Required
Every commit must carry a Signed-off-by trailer certifying the Developer Certificate of Origin. Commits
without it are not accepted.
That appends:
To fix an existing branch, amend a single commit with git commit --amend -s or rebase a series with
git rebase --signoff main. The full Developer Certificate of Origin (DCO) text is reproduced in
CONTRIBUTING.md. Sign-off is distinct from GitHub signed (GPG-verified) commits, which affect CI
triggering only.
Pull Request Flow
To prepare and submit a pull request, complete the following steps:
-
Open an issue first for a significant change so contributors can discuss the approach.
-
Fork the repository and create a branch from
mainwith a descriptive name (feature/...,fix/...). -
Implement the change together with tests and documentation updates.
-
Run the gates locally:
-
Push to your fork and open a pull request against
mainthat describes what changed and why. -
Address review feedback, and squash the history before merge.
Triggering CI
The pipeline runs on pushes to main, to deploy-release/*, and to the bot-mirrored
pull-request/<number> branches. If your GitHub account uses signed (GPG-verified) commits, CI starts
automatically on each push. Otherwise, comment on the pull request with the SHA of the commit you want tested:
Repeat the comment for each new commit. Get the SHA from git log --oneline -1.
Documentation-only pull requests take a different path: fern-docs-ci.yml and
fern-docs-preview-build.yml have a docs/** path filter and gate on MDX safety, fern check, and offline
link checking. Refer to
Building the Docs before editing anything under docs/.
Where Changes Usually Go
Use this table to find the documentation and implementation guidance for a change:
Local artifacts are gitignored and must not be committed: .venv/, nemo_voice_agent.egg-info/,
nemo_experiments/, eval_results/, and *.log files.