From bb4fda6f0e94cfa2de8ad6d7675c40898557857f Mon Sep 17 00:00:00 2001 From: Richard Palethorpe Date: Wed, 22 Apr 2026 21:43:01 +0100 Subject: [PATCH] chore(agents): Update the backend creation instructions to include Rust and extra tests (#9490) Signed-off-by: Richard Palethorpe --- .agents/adding-backends.md | 35 ++++++++++++++++++++++++++++++----- .agents/coding-style.md | 6 ++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.agents/adding-backends.md b/.agents/adding-backends.md index 02b13dd28..2ea3b41cb 100644 --- a/.agents/adding-backends.md +++ b/.agents/adding-backends.md @@ -8,6 +8,7 @@ Create the backend directory under the appropriate location: - **Python backends**: `backend/python//` - **Go backends**: `backend/go//` - **C++ backends**: `backend/cpp//` +- **Rust backends**: `backend/rust//` For Python backends, you'll typically need: - `backend.py` - Main gRPC server implementation @@ -18,9 +19,22 @@ For Python backends, you'll typically need: - `run.sh` - Runtime script - `test.py` / `test.sh` - Test files +For Rust backends, you'll typically need (see `backend/rust/kokoros/` as a reference): +- `Cargo.toml` - Crate manifest; depend on the upstream project as a submodule under `sources/` +- `build.rs` - Invokes `tonic_build` to generate gRPC stubs from `backend/backend.proto` (use the `BACKEND_PROTO_PATH` env var so the Makefile can inject the canonical copy) +- `src/` - The gRPC server implementation (implement `Backend` via `tonic`) +- `Makefile` - Copies `backend.proto` into the crate, runs `cargo build --release`, then `package.sh` +- `package.sh` - Uses `ldd` to bundle the binary's dynamic deps and `ld.so` into `package/lib/` +- `run.sh` - Sets `LD_LIBRARY_PATH`/`SSL_CERT_DIR` and execs the binary via the bundled `lib/ld.so` +- `sources//` - Git submodule with the upstream Rust crate + ## 2. Add Build Configurations to `.github/workflows/backend.yml` -Add build matrix entries for each platform/GPU type you want to support. Look at similar backends (e.g., `chatterbox`, `faster-whisper`) for reference. +Add build matrix entries for each platform/GPU type you want to support. Look at similar backends for reference — `chatterbox`/`faster-whisper` for Python, `piper`/`silero-vad` for Go, `kokoros` for Rust. + +**Without an entry here no image is ever built or pushed, and the gallery entry in `backend/index.yaml` will point at a tag that does not exist.** The `dockerfile:` field must point at `./backend/Dockerfile.` matching the language bucket from step 1 (e.g. `Dockerfile.python`, `Dockerfile.golang`, `Dockerfile.rust`). The `tag-suffix` must match the `uri:` in the corresponding `backend/index.yaml` image entry exactly. + +If you add a new language bucket, `scripts/changed-backends.js` also needs a branch in `inferBackendPath` so PR change-detection routes file edits correctly. **Placement in file:** - CPU builds: Add after other CPU builds (e.g., after `cpu-chatterbox`) @@ -56,24 +70,28 @@ Add `backends/` to the `.NOTPARALLEL` line (around line 2) to prev **Step 4b: Add to `prepare-test-extra`** -Add the backend to the `prepare-test-extra` target (around line 312) to prepare it for testing: +Add the backend to the `prepare-test-extra` target to prepare it for testing. Use the path matching your language bucket (`backend/python/`, `backend/go/`, `backend/rust/`, …): ```makefile prepare-test-extra: protogen-python ... - $(MAKE) -C backend/python/ + $(MAKE) -C backend// ``` +For Rust backends the target is usually the crate build target itself (e.g. `$(MAKE) -C backend/rust/ -grpc`) so the binary is in place before `test` runs. + **Step 4c: Add to `test-extra`** -Add the backend to the `test-extra` target (around line 319) to run its tests: +Add the backend to the `test-extra` target to run its tests — applies to Go and Rust backends too, not only Python: ```makefile test-extra: prepare-test-extra ... - $(MAKE) -C backend/python/ test + $(MAKE) -C backend// test ``` +Each backend's own `Makefile` should define a `test` target so this line works regardless of language. Integration tests that need large model downloads should be gated behind an env var (see `backend/rust/kokoros/`'s `KOKOROS_MODEL_PATH` pattern) so CI only runs unit tests. + **Step 4d: Add Backend Definition** Add a backend definition variable in the backend definitions section (around line 428-457). The format depends on the backend type: @@ -93,6 +111,13 @@ BACKEND_ = |python|./backend|false|true BACKEND_ = |golang|.|false|true ``` +**For Rust backends**: +```makefile +BACKEND_ = |rust|.|false|true +``` + +The language field (`python`/`golang`/`rust`/…) must match a `backend/Dockerfile.` file. + **Step 4e: Generate Docker Build Target** Add an eval call to generate the docker-build target (around line 480-501): diff --git a/.agents/coding-style.md b/.agents/coding-style.md index bedb4f439..6ead2ef98 100644 --- a/.agents/coding-style.md +++ b/.agents/coding-style.md @@ -42,6 +42,12 @@ trim_trailing_whitespace = false Use `github.com/mudler/xlog` for logging which has the same API as slog. +## Go tests + +All Go tests — including backend tests — must use [Ginkgo](https://onsi.github.io/ginkgo/) (v2) with Gomega matchers, not the stdlib `testing` package with `t.Run` / `t.Errorf`. A test file should register a suite with `RegisterFailHandler(Fail)` in a `TestXxx(t *testing.T)` bootstrap and use `Describe`/`Context`/`It` blocks for the actual cases. Look at any existing `*_test.go` under `core/` or `pkg/` for a template. + +Do not mix styles within a package. If you are extending tests in a package that already uses Ginkgo, keep using Ginkgo. If you find stdlib-style Go tests in the tree, treat them as tech debt to be migrated rather than as a pattern to follow. + ## Documentation The project documentation is located in `docs/content`. When adding new features or changing existing functionality, it is crucial to update the documentation to reflect these changes. This helps users understand how to use the new capabilities and ensures the documentation stays relevant.