Files
localmodelroutex/CONTRIBUTING.md
LovroG05 353af96238 chore: add AGPL-3.0 license, contributing guide and security policy
Prepare the repository for a public release. Ignore local Claude Code
session files.
2026-10-04 17:32:44 +02:00

103 lines
3.8 KiB
Markdown

# Contributing to LMR
Thanks for your interest. This page tells you how to set up a development
environment, how to run the checks, and what a good pull request looks like.
## Development setup
You need Go 1.27 or newer, Node 22 or newer, Docker, and `make`.
```bash
cd backend
cp .env.example .env
echo GATEWAY_SECURITY_ENCRYPTION_KEY=$(openssl rand -hex 32) >> .env
make dev
```
`make dev` starts a Postgres container, applies the migrations, runs the Go
server on port 8080, and runs the Vite dev server on port 5173 with a proxy to
the Go server. The dashboard needs an OIDC provider to sign in. Any provider
works; the `.env.example` file shows the Authentik shape.
Run `make help` to list every target.
## Checks
Run these before you open a pull request. The CI pipeline runs the same set.
```bash
cd backend
go vet ./...
make test # unit tests, no database needed
make lint # golangci-lint, config in backend/.golangci.yml
cd dashboard && npx tsc --noEmit && npm run build
```
### Database tests
The `internal/store` and `internal/catalog` packages have integration tests
against a real Postgres. They skip unless `GATEWAY_TEST_DB_URL` is set.
```bash
cd backend
make dev-db # or any Postgres 16
export GATEWAY_TEST_DB_URL='postgres://gateway:gateway@localhost:5432/gateway?sslmode=disable'
GATEWAY_DB_URL=$GATEWAY_TEST_DB_URL go run ./cmd/migrate up
go test ./internal/store/ ./internal/catalog/
```
The tests delete and recreate rows, so point them at a throwaway database.
## Project layout
See the "Repo layout" section of the [README](README.md) and the
[architecture notes](docs/ARCHITECTURE.md). The short version:
- `backend/internal/api` holds the HTTP handlers.
- `backend/internal/providers` holds the provider abstraction. Each upstream
type lives in its own package and registers itself in `init()`.
- `backend/internal/catalog` holds the runtime model library.
- `backend/internal/store` holds hand-written SQL on `pgx`.
- `backend/migrations` holds the schema. Add a new numbered pair of
`up` and `down` files for every schema change. Never edit an applied one.
- `backend/dashboard` holds the React UI. The Go binary embeds the build.
## Adding a provider
1. Create `backend/internal/providers/<type>/` with a `New` factory and an
`init()` that calls `providers.Register`.
2. Implement the capability interfaces the upstream supports:
`ChatCompleter`, `Embedder`, `ImageGenerator`, `ModelLister`.
3. Import the package in `backend/internal/providers/all`.
4. If the upstream is OpenAI-compatible, embed `openaicompat.Transport` and
only add what differs. See the `openrouter` package for an example.
5. Add the type to the providers table in the README and to the dashboard's
provider form.
## Pull requests
- Keep one change per pull request.
- Add or update tests for the code you touch. Handler tests live in
`backend/internal/api` and use fake dependencies, so they do not need a
database.
- Run `gofmt`. The lint step fails on unformatted code.
- Write commit messages as `<area>: <short summary>` in the imperative mood,
for example `catalog: store output modalities as capabilities`. Explain the
reason in the body when it is not obvious from the diff.
- Do not include generated files. The `internal/web/dist` folder and `bin/`
are ignored on purpose.
## Reporting bugs
Open an issue with the version or commit, the steps to reproduce, the expected
result, and the actual result. For a request that failed at the proxy, include
the row from the Logs page with the key prefix removed.
Security problems go to the address in [SECURITY.md](SECURITY.md), not to the
issue tracker.
## License
By contributing you agree that your contributions are licensed under the
GNU Affero General Public License, version 3, the same as the project.