Skip to content

feat(rust): add OpenEngine bindings crate - #9

Open
connorcarpenter15 wants to merge 7 commits into
mainfrom
feat/package-releases
Open

connorcarpenter15 wants to merge 7 commits into
mainfrom
feat/package-releases

Conversation

@connorcarpenter15

@connorcarpenter15 connorcarpenter15 commented Jul 10, 2026

Copy link
Copy Markdown

Summary

  • add the publishable openengine Rust crate with checked-in Prost messages and Tonic client/server bindings for the current openengine.v1 schema
  • expose the immutable BSR schema release, schema revision, and complete protobuf descriptor set
  • add pinned, reproducible Rust generation and generated-code drift checks
  • validate the crate on Rust 1.88 and stable, including Clippy, rustdoc, and the staged crates.io package
  • add openengine-v* tag-driven crates.io Trusted Publishing with a documented first-release bootstrap

Why

Rust clients and engine implementations should be able to depend on OpenEngine without cloning the schema repository or running Buf or protoc in consumer builds.

Scope

This PR publishes only the Rust crate. It does not add a Python package or Python release automation.

Public API

use openengine::v1::{control_client::ControlClient, inference_client::InferenceClient};

The initial crate version is 0.1.0 and identifies immutable BSR commit 768a93c7b44e40f28c692ad0b471a8f2.

Validation

  • generated binding drift check
  • cargo fmt --all --check
  • cargo check --locked --workspace --all-targets
  • cargo +1.90 check --locked --workspace --all-targets (oldest locally installed toolchain; CI covers declared Rust 1.88 MSRV)
  • cargo clippy --locked --workspace --all-targets -- -D warnings
  • RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps --package openengine
  • cargo package --locked --package openengine
  • release tag/version guard
  • Markdown lint

No custom serialization tests are added: Buf validation, deterministic regeneration, Prost/Tonic compilation, and cargo package already cover the generated protocol and distribution boundaries.

Connor Carpenter added 2 commits July 10, 2026 12:23
Signed-off-by: Connor Carpenter <connorc@nvidia.com>
Signed-off-by: Connor Carpenter <connorc@nvidia.com>
Connor Carpenter added 2 commits September 3, 2026 12:52
Signed-off-by: Connor Carpenter <connorc@nvidia.com>
Signed-off-by: Connor Carpenter <connorc@nvidia.com>
@connorcarpenter15 connorcarpenter15 changed the title feat(packages): add Python and Rust releases feat(rust): add OpenEngine bindings crate Sep 3, 2026
Signed-off-by: Connor Carpenter <connorc@nvidia.com>
Comment thread RELEASING.md
alec-flowers
alec-flowers previously approved these changes Sep 3, 2026

@dagil-nvidia dagil-nvidia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One blocker, four judgment calls. The release workflow cannot publish as written, because crates.io rejects the User-Agent its probes send.

Blocker: Missing User-Agent on the crates.io Probes

.github/workflows/rust-release.yml:54,57 call curl with no --user-agent. crates.io blocks the default curl/8.x at the CDN edge under its data access policy and returns 403 with an empty body. There is no 403 arm in the case block, so both probes reach *) and exit 1. That fails validate, publish is skipped through needs, and every openengine-v* tag push stops there.

Only the agent changed between these two runs:

User-Agent Crate that exists Crate that does not
default curl/8.x 403 403
openengine-release (+URL) 200 404

The same block broke nixpkgs CI (crates.io#13482). The replacement value cannot contain the substring curl, which is blocked on its own (crates.io#13783).

One flag on both lines:

ua="openengine-release (+https://github.com/ai-dynamo/openengine)"
status="$(curl --silent --user-agent "${ua}" --output /dev/null --write-out '%{http_code}' "${url}")"

Consider

  • rust-release.yml:57-62 - the idempotency guard assumes cargo package produces byte-identical output across two runners at two points in time. Pinning the release toolchain to an exact version removes the variable.
  • packages/rust/openengine/src/lib.rs:11 - SCHEMA_RELEASE agrees with all three doc sites today and nothing enforces it. A grep in CI would.
  • rust.yml paths: filters - these four checks cannot be made required once this lands. A path-filtered check never reports on a PR it filtered out, so requiring them would block every docs-only PR.
  • tools/rust-codegen/src/main.rs - unwrap_or(env::current_dir()?) at 7-10 evaluates its argument eagerly, and env::set_var at 29 becomes unsafe in edition 2024. Neither is reachable as a bug today.
  • New Rust sources carry no SPDX header, where all eight .proto files and every Markdown file do. This PR adds the repository's first non-proto source, so it sets the precedent.

Verified

  • scripts/check-generated.sh reproduces both generated artifacts byte for byte on macOS arm64 under rustc 1.98, a different platform and toolchain than CI. Changing a field in lifecycle.proto fails it on both the .rs and the descriptor, so it regenerates rather than only diffing.
  • scripts/check-release-version.sh accepts a matching tag and rejects a mismatched one.
  • cargo package --list ships exactly the intended files, the crate carries its own license, the Trusted Publishing setup uses no long-lived token, and the crate name is unclaimed on crates.io.

Pre-existing

buf.yml:25 and buf-push.yml:45 pin actions/checkout@v4, and docs.yml:28,43 use @v6 tags. Not introduced here, and the new workflows are better pinned than these.

Signed-off-by: Connor Carpenter <connorc@nvidia.com>
@tanmayv25

Copy link
Copy Markdown
Contributor

I reviewed this for the intended Dynamo Rust sidecar -> TensorRT-LLM Python gRPC server integration. I found three items worth addressing or coordinating:

  1. Release CI does not validate the advertised schema identity. SCHEMA_REVISION and SCHEMA_RELEASE are hardcoded in packages/rust/openengine/src/lib.rs, while generation and release CI only verify that bindings match the checked-out proto and that the crate version matches the tag. A future schema change could therefore regenerate and publish successfully with stale identity constants. A sidecar performing compatibility checks against ServerInfo could then incorrectly accept or reject the TRT-LLM server. The current v0.1.0 values are correct; this is a forward release-invariant gap. Suggested fix: keep crate version, schema revision, and immutable schema identifier in one machine-readable release manifest, generate or validate the constants from it, and verify the descriptor against the declared schema artifact before publication.

  2. The published crate README links to the moving main schema. packages/rust/openengine/README.md becomes the crates.io README for version 0.1.0, but its openengine.v1 link points to tree/main. Since this experimental schema may change incompatibly, that page can eventually describe a different contract from the packaged bindings. Please pin the link to v0.1.0 or the immutable schema commit.

  3. The TRT-LLM sidecar must consistently use the Tonic 0.14 transport path. This crate exposes Tonic/Prost 0.14 types, while the current sidecar pins Tonic 0.13.1 and Prost 0.13.5. Those versions can coexist, but Channel, Status, Request, and generated message types cannot cross the 0.13/0.14 boundary. Dynamo already provides dynamo_sidecar_common::v14, so the intended fix is to enable and use that path when adopting this crate; this is not a request to downgrade OpenEngine to Tonic 0.13.

The Python server does not need grpcio/protobuf versions matching Rust Tonic/Prost. Its separate constraint is that TRT-LLM generated Python code must be compatible with its installed Python runtimes, so its generator should be pinned and its runtime floors validated independently.

Signed-off-by: tanmayv25 <tanmay2592@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants